Compare commits
441 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c2e5e45c84 | |||
| 014236c861 | |||
| 610fd7561b | |||
| d6f4480a4f | |||
| 28a6ac09ad | |||
| 86e4d24476 | |||
| 913a697ab2 | |||
| ebef2b1e44 | |||
| a61457b422 | |||
| 8f7f1135df | |||
| 89612c10c9 | |||
| d55bfb32f1 | |||
| d2b72cf496 | |||
| 8d90fffd46 | |||
| b84af27a86 | |||
| b45f28f3e9 | |||
| bfa1b5656a | |||
| 47f946cd65 | |||
| 970e7bfcda | |||
| a81c7a7cd6 | |||
| b0e1bd239f | |||
| 53ca41717a | |||
| 6a5bee0cdd | |||
| fd3ae51f83 | |||
| 5e5954a808 | |||
| add8540909 | |||
| 06a302aed0 | |||
| 147432d38d | |||
| 2a003ff72b | |||
| 8660d3324d | |||
| 6c59b73ae5 | |||
| 80218c1eca | |||
| f24d96d59f | |||
| d14bd49f46 | |||
| 1a692a0873 | |||
| 631a1a4ddc | |||
| 57df7601d9 | |||
| f7650000aa | |||
| 6f93c2d9b2 | |||
| 1654764968 | |||
| 1a1b8416e2 | |||
| 36c66d52a6 | |||
| 68fe43d488 | |||
| 877b9ee23b | |||
| 80ff93beeb | |||
| b9ddd2812b | |||
| ba54b56de4 | |||
| 85be67bc2d | |||
| ae20e01d2c | |||
| d094e8c3fc | |||
| f009fe1f63 | |||
| 2007fe5f49 | |||
| 84989ffa04 | |||
| 31b629a19c | |||
| e762d9e274 | |||
| 6833267b19 | |||
| 05f2833388 | |||
| 0d026ef18d | |||
| b756d93891 | |||
| f54513586d | |||
| 6c519c237e | |||
| 4ffde4db98 | |||
| 41847d31e7 | |||
| 24ce25bb5c | |||
| e051b69e80 | |||
| 59283d1164 | |||
| 0de32a5edc | |||
| 4f80066dcb | |||
| 04ddc8003f | |||
| 3213f98d66 | |||
| 1f16f85c51 | |||
| c03cb3a11c | |||
| 62e29a6546 | |||
| 3574b065d6 | |||
| c0c47f41be | |||
| 37761d580f | |||
| e075c8e691 | |||
| 0c61ca1a6b | |||
| 1846fa1f54 | |||
| 579ce20cad | |||
| 12e4bcba5d | |||
| b4f57dee3b | |||
| f11673ae3f | |||
| a27af7dd7e | |||
| 2b26a3cc14 | |||
| 47c4849694 | |||
| 30a4adf331 | |||
| 117a721166 | |||
| 1a219e62ba | |||
| c8d54b324b | |||
| 0ac2971fc1 | |||
| 348a40201b | |||
| 9f20ddc800 | |||
| 6f1cc2c1e5 | |||
| 601cd95277 | |||
| 8e9ce59ef2 | |||
| d76ef8e3cf | |||
| c19ffafd8d | |||
| 996a99ad75 | |||
| affb926d44 | |||
| c506e534aa | |||
| 9994315070 | |||
| 4f0d89ef8b | |||
| aab984618d | |||
| 8b662bc6b5 | |||
| 03ce7a8db3 | |||
| 033e7928b5 | |||
| b095f2a158 | |||
| 196c0e0ebc | |||
| 8ab309630b | |||
| 42bac47a71 | |||
| 3bc4de2236 | |||
| a6e4b45a38 | |||
| 28e97ccaf2 | |||
| 255781c029 | |||
| 7f5635ea8c | |||
| 4f18ec726c | |||
| 263622d628 | |||
| 1dfd2443ac | |||
| 881bd53f60 | |||
| ec4404b1ba | |||
| badaeac81f | |||
| 618d5ddaff | |||
| 4ed74af868 | |||
| 123d9af7d0 | |||
| 4f17b30915 | |||
| 1fc265b0aa | |||
| afae9b8d17 | |||
| 481be44879 | |||
| b8530b0f0b | |||
| 69de79684f | |||
| 6e6fd057b5 | |||
| 4b0ebf2b80 | |||
| ee82c32119 | |||
| 3fe6731035 | |||
| 1c3f3b5705 | |||
| def1ccffc4 | |||
| fa2e531343 | |||
| 814ddbc6cc | |||
| 267e8dcfb6 | |||
| 49ec1561f8 | |||
| e2dc612153 | |||
| 8f225431fe | |||
| 194be5e0b7 | |||
| 6788a05dd1 | |||
| 6a7066ac2f | |||
| ec5ff4e973 | |||
| fe6d460531 | |||
| 9cb97af10f | |||
| 1c784eea3d | |||
| 59dd33a461 | |||
| 97ebd912dc | |||
| 742fcc060c | |||
| 3ad5cb8a23 | |||
| 0d1f12e31a | |||
| a8ddf8f66d | |||
| f7a9c0a248 | |||
| 190badb395 | |||
| 3d91ab6c31 | |||
| c15b8d71bc | |||
| 5a707dba8a | |||
| ffd2fcde6b | |||
| 8e4056c1e4 | |||
| 1554e2b135 | |||
| 4715cbb70d | |||
| fd1611079a | |||
| 8edc03df64 | |||
| 9f5c0af5b8 | |||
| 6d6eeba5d5 | |||
| 5dfb64ef71 | |||
| e5bda7add7 | |||
| 77f9b336bd | |||
| cf930d0dde | |||
| f01c94e8bc | |||
| 0d774527b4 | |||
| 58ba9496d0 | |||
| 1993e94e53 | |||
| 3bcc06ed09 | |||
| 2f6ce88e28 | |||
| cd1dec9fc7 | |||
| 05872d7650 | |||
| 1dcee2ffa2 | |||
| 5f622efb77 | |||
| 52e8326d54 | |||
| 436532bed7 | |||
| d15e789200 | |||
| 98942f5528 | |||
| c7c21dc122 | |||
| 4500c1d1a4 | |||
| b8b983dded | |||
| d6a6673971 | |||
| 0580fe8db8 | |||
| c727e24138 | |||
| b83698ebf5 | |||
| 3fbbaa5130 | |||
| 2f48b840ae | |||
| efdee11d5a | |||
| 4c87e11aeb | |||
| e881e008b8 | |||
| 1b2837915d | |||
| d076a6724f | |||
| 386af71c39 | |||
| 49f277192c | |||
| 5974a6276b | |||
| e06a390771 | |||
| b34e204676 | |||
| 755d990dfd | |||
| 7185358b98 | |||
| 3843ec1e02 | |||
| cfc5631d5d | |||
| e64555aca0 | |||
| ef52ebb529 | |||
| c98136ca4f | |||
| 65f44d24ca | |||
| 44f20782fd | |||
| 9b1d76a5d0 | |||
| 21b5074ce8 | |||
| 0b8825fecb | |||
| 3d3c20e507 | |||
| 67a282f19f | |||
| 92023b533a | |||
| c1d14c150e | |||
| aa656c74d5 | |||
| e39b7ffe30 | |||
| 1897148abc | |||
| b76118802a | |||
| 8266aa3343 | |||
| ab0c349261 | |||
| d5e0e66426 | |||
| c5b3107f83 | |||
| 1a0a64e4de | |||
| 6bd9805bcc | |||
| f74c2af65c | |||
| 9531bdf674 | |||
| 76e705e7ee | |||
| d35211328e | |||
| b7bbd81dda | |||
| 9836dd5d10 | |||
| 2109ad320d | |||
| c026121c0e | |||
| ee0c87f7b1 | |||
| 709fb93a22 | |||
| b38cd0a48d | |||
| 264435c32d | |||
| c285929ad3 | |||
| 1cbea8157d | |||
| 0a10334f1b | |||
| f0d5a6ebac | |||
| db7086b5e6 | |||
| 0e92280b33 | |||
| 0d7255158a | |||
| 33564b68dd | |||
| ba942b952a | |||
| bd7f28896e | |||
| 18fe124696 | |||
| ea3a3b6e1c | |||
| e6c06aacff | |||
| 1aee92cd5c | |||
| 40c4cad491 | |||
| 013d46fb02 | |||
| f0f465411f | |||
| 32ce83475d | |||
| ec0d3f5b5d | |||
| 75294b9146 | |||
| 26a0eb68ef | |||
| b983e29fb0 | |||
| 68dadabc29 | |||
| ed9fd3f0e0 | |||
| fa9573436a | |||
| 6d2058c3b7 | |||
| 0d7f93b877 | |||
| f022c9d510 | |||
| 5964a06386 | |||
| f14dc4a4e9 | |||
| fd56e2534c | |||
| 08962a74ab | |||
| f850d36c52 | |||
| c5fb161477 | |||
| bfc2fab33f | |||
| ec9d6c4fd2 | |||
| 6135d61e3d | |||
| a677242a2c | |||
| 6602f30112 | |||
| a4b8dc18c1 | |||
| c0d4741f88 | |||
| b33718180c | |||
| 3872393b29 | |||
| 1d72a7df99 | |||
| 5455908772 | |||
| 8882192fac | |||
| 7b77491c06 | |||
| 20bf214d6e | |||
| 8ab3e63aeb | |||
| 0dc03214c5 | |||
| 362e98b43d | |||
| 193e085cf0 | |||
| e0df2a342b | |||
| ba19ccac43 | |||
| d7261b7a78 | |||
| 0d80173efd | |||
| 930f07d15e | |||
| 66df7389d2 | |||
| c7bf0b6ddd | |||
| 0bc361adeb | |||
| 4fff523a6d | |||
| 67e09fb342 | |||
| c360806f47 | |||
| 7b74b73b08 | |||
| e9a851c0d4 | |||
| b13b169149 | |||
| 455329a745 | |||
| a68b76c8b4 | |||
| 96e3899216 | |||
| 771ab5ea9a | |||
| 3c87e6b270 | |||
| 6d8afec510 | |||
| 89e25657d8 | |||
| 29387f1fcf | |||
| 58e885c052 | |||
| 984dfcd7e1 | |||
| 3785479086 | |||
| 8ed280907c | |||
| d742671205 | |||
| 87e72c28a4 | |||
| 4dee357362 | |||
| 431f4b9b0d | |||
| dd5b7825d5 | |||
| 02bc48925a | |||
| 4eb505755e | |||
| 83e94a70ea | |||
| 8a150b27c3 | |||
| 1a51451ec2 | |||
| 41e51bfb77 | |||
| 7e1d9bc768 | |||
| ba065ec1d8 | |||
| fe057a91c8 | |||
| d2c36eefc9 | |||
| 28d56bab04 | |||
| 2500eff90d | |||
| 153446b3a1 | |||
| 391f5caaa2 | |||
| cc0df92444 | |||
| 03910d67c3 | |||
| fec5cc864e | |||
| cb78362713 | |||
| 4c5b1a6ff4 | |||
| 83c5727698 | |||
| 80838ff1e9 | |||
| 29e8d072b7 | |||
| d7592f01e1 | |||
| 392f283d9e | |||
| bcd738ebbb | |||
| 8020c52c48 | |||
| 3f566e541d | |||
| be4a631dc8 | |||
| 0bfdf908c1 | |||
| 6f2fc23f77 | |||
| f3a47c7e70 | |||
| 36349ffabb | |||
| b13f7366cf | |||
| 9181bcd9a7 | |||
| 7dbc1d894b | |||
| 5720445d15 | |||
| a90027521d | |||
| e02d400bf6 | |||
| efadb8fd31 | |||
| a19d06561b | |||
| 0b685d11c9 | |||
| 28f019d672 | |||
| bf5cbfffc2 | |||
| fe021e7c51 | |||
| c42fb54bc6 | |||
| 9382b68781 | |||
| 178198a417 | |||
| 7068e90771 | |||
| 1c762f23d0 | |||
| fd2b9a6e21 | |||
| db43910288 | |||
| f248c0460e | |||
| b8e3c0ceb4 | |||
| b5053d889e | |||
| 12ba7776b3 | |||
| 7817e88d03 | |||
| 8dec65853d | |||
| 88e3cb3be1 | |||
| fa702b48e3 | |||
| 299dcf6686 | |||
| 27f9ae5bbb | |||
| 9cb3a853f1 | |||
| 95c8ef4148 | |||
| a41bb52014 | |||
| 914cd7221e | |||
| 2dfc0a58ab | |||
| 0c9f3c638a | |||
| a966d6acf1 | |||
| 1e0c38b5f9 | |||
| d3323d6550 | |||
| ebed0b9f20 | |||
| f654a453dc | |||
| 10decf94cc | |||
| 96dd4817f1 | |||
| 72906cdc6a | |||
| fba4375be0 | |||
| 75120676ad | |||
| 7daf63fd3f | |||
| 014de25f6f | |||
| 3fc6535012 | |||
| 4fc0a32572 | |||
| dcc704a357 | |||
| bd8acbde97 | |||
| 112b10c19d | |||
| d89e561a85 | |||
| 49c1da79c8 | |||
| 0a72f00175 | |||
| 1af5820db0 | |||
| c117491549 | |||
| d8748f4270 | |||
| c0ba6e13e4 | |||
| c34daf1a35 | |||
| d461b53235 | |||
| c3ee14eb67 | |||
| 869fb8e327 | |||
| fbbc3024d6 | |||
| f1ba0c0aa7 | |||
| 54340ab4bf | |||
| 39732eee5e | |||
| a9e4526a6d | |||
| 57a6d2abf9 | |||
| d6246941ac | |||
| 2eb91f9b91 | |||
| 34ae413607 | |||
| ee9f8c184b | |||
| 7a84afcbdb | |||
| b8a16ea99d | |||
| 095466d5c7 | |||
| 1f18050930 | |||
| 537b78d564 | |||
| 717fd57ce1 | |||
| 3fb7786868 | |||
| 17ecfc9765 | |||
| 5326260a76 |
@@ -1,5 +1,6 @@
|
|||||||
syntax: regexp
|
syntax: regexp
|
||||||
|
|
||||||
|
^\.bzr
|
||||||
^ChangeLog
|
^ChangeLog
|
||||||
^build
|
^build
|
||||||
^maint
|
^maint
|
||||||
@@ -7,37 +8,41 @@ syntax: regexp
|
|||||||
syntax: glob
|
syntax: glob
|
||||||
|
|
||||||
*.a
|
*.a
|
||||||
*.d
|
|
||||||
*.dll
|
*.dll
|
||||||
*.exe
|
|
||||||
*.lib
|
*.lib
|
||||||
*.map
|
|
||||||
*.o
|
|
||||||
*.out
|
|
||||||
*.py[cdo]
|
*.py[cdo]
|
||||||
*.so
|
*.so
|
||||||
*.res
|
*.swp
|
||||||
*.ttp
|
|
||||||
|
|
||||||
doc/*.1
|
doc/*.1
|
||||||
doc/*.doc
|
doc/*.doc
|
||||||
doc/*.html
|
doc/*.html
|
||||||
|
doc/*.man
|
||||||
|
doc/*.ps
|
||||||
|
doc/*.tex
|
||||||
|
|
||||||
|
src/GNUmakefile
|
||||||
src/MMakefile
|
src/MMakefile
|
||||||
src/compress_nrv*
|
src/compress_nrv*
|
||||||
|
src/*.mft
|
||||||
src/*.rc
|
src/*.rc
|
||||||
|
|
||||||
stub/MMakefile
|
src/*.d
|
||||||
stub/l_t_*.i
|
src/*.exe
|
||||||
stub/stamp-h
|
src/*.map
|
||||||
stub/*.ash
|
src/*.o
|
||||||
stub/*.asx
|
src/*.obj
|
||||||
stub/*.asy
|
src/*.out
|
||||||
stub/*.bin
|
src/*.res
|
||||||
stub/*.lst
|
src/*.ttp
|
||||||
|
|
||||||
stub/util/armpe/armpe_tester
|
stub/**MMakefile
|
||||||
|
stub/**.*-stamp
|
||||||
|
stub/tmp*/*
|
||||||
|
stub/**/tmp*/*
|
||||||
|
|
||||||
stub/util/sstrip/amd64-linux-sstrip
|
stub/tools/armpe/armpe_tester
|
||||||
stub/util/sstrip/i386-linux-sstrip
|
|
||||||
stub/util/sstrip/sstrip
|
stub/tools/sstrip/amd64-linux-sstrip
|
||||||
|
stub/tools/sstrip/i386-linux-sstrip
|
||||||
|
stub/tools/sstrip/sstrip
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
||||||
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||||
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||||
|
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
||||||
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
||||||
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
||||||
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
# Toplevel Makefile for UPX
|
#
|
||||||
|
# UPX toplevel Makefile - needs GNU make 3.80 or better
|
||||||
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
@@ -8,26 +10,38 @@ srcdir = .
|
|||||||
top_srcdir = .
|
top_srcdir = .
|
||||||
|
|
||||||
|
|
||||||
|
# info: src/stub needs GNU make 3.81 and special build tools
|
||||||
|
BUILD_STUB = 0
|
||||||
|
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||||
|
BUILD_STUB = 1
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||||
|
BUILD_STUB = 1
|
||||||
|
endif
|
||||||
|
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.79 3.79.1 3.80),)
|
||||||
|
BUILD_STUB = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@echo "UPX info: please choose a target for 'make'"
|
@echo "UPX info: please choose a target for 'make'"
|
||||||
|
|
||||||
all mostlyclean clean distclean maintainer-clean:
|
all mostlyclean clean distclean maintainer-clean:
|
||||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx),)
|
ifeq ($(BUILD_STUB),1)
|
||||||
# these need special build tools
|
|
||||||
$(MAKE) -C src/stub/util/sstrip $@
|
|
||||||
$(MAKE) -C src/stub $@
|
$(MAKE) -C src/stub $@
|
||||||
endif
|
endif
|
||||||
$(MAKE) -C src $@
|
$(MAKE) -C src $@
|
||||||
$(MAKE) -C doc $@
|
$(MAKE) -C doc $@
|
||||||
|
|
||||||
dist: distclean
|
# automatically generate ChangeLog from Mercurial repo
|
||||||
false
|
|
||||||
|
|
||||||
# automatically generate ChangeLog from hg
|
|
||||||
ChangeLog:
|
ChangeLog:
|
||||||
|
ifneq ($(wildcard .hg/data/.),)
|
||||||
hg log --style=changelog > $@
|
hg log --style=changelog > $@
|
||||||
|
else
|
||||||
|
@echo "UPX info: no hg repo found"
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||||
.PHONY: dist ChangeLog
|
.PHONY: ChangeLog
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,23 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
Changes in 2.90 (08 Oct 2006):
|
||||||
|
* LZMA algorithm support for most of the 32-bit and 64-bit file formats;
|
||||||
|
use new option '--lzma' to enable
|
||||||
|
* new format: BSD/elf386 supporting FreeBSD, NetBSD and OpenBSD
|
||||||
|
via auto-detection of PT_NOTE or EI_OSABI
|
||||||
|
* arm/pe: all the NRV compression methods are now supported
|
||||||
|
(only NRV2D is missing in thumb mode)
|
||||||
|
* linux/elf386, linux/ElfAMD remember /proc/self/exe in environment
|
||||||
|
* vmlinuz/386: fixed zlib uncompression problem on dos
|
||||||
|
* major source code change: the runtime decompression stubs are now
|
||||||
|
built from internal ELF objects
|
||||||
|
|
||||||
|
Changes in 2.02 (13 Aug 2006):
|
||||||
|
* linux/386: work around Linux kernel bug (".bss" requires PF_W)
|
||||||
|
* linux/ppc32, mach/ppc32: compressed programs now work on a 405 CPU
|
||||||
|
* vmlinuz/386: fixed zlib uncompression problem on dos
|
||||||
|
|
||||||
Changes in 2.01 (06 Jun 2006):
|
Changes in 2.01 (06 Jun 2006):
|
||||||
* arm/pe: better DLL support
|
* arm/pe: better DLL support
|
||||||
* dos/exe: device driver support added
|
* dos/exe: device driver support added
|
||||||
|
|||||||
+11
-13
@@ -13,21 +13,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
MAJOR NEWS IN UPX 2
|
WARNING - UNSTABLE BETA VERSION
|
||||||
|
===============================
|
||||||
|
|
||||||
|
The current stable release is 2.02, and the next stable release
|
||||||
|
will be called version 3.00.
|
||||||
|
|
||||||
|
|
||||||
|
MAJOR NEWS IN UPX 3
|
||||||
===================
|
===================
|
||||||
|
|
||||||
The main news since 1.25 are:
|
The main news since UPX 2 are:
|
||||||
|
|
||||||
* new format: added support for arm/pe (ARM executables running on WinCE)
|
* new format: added support for linux elf/arm
|
||||||
* new format: added support for linux elf/amd64
|
|
||||||
* new format: added support for linux elf/ppc32
|
|
||||||
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
|
||||||
* new format: added support for bootable Linux kernels ("vmlinuz/386")
|
|
||||||
* new format: added support for Playstation exes ("ps1/exe")
|
|
||||||
|
|
||||||
* slightly better compression using the new NRV2E algorithm
|
* better compression using the LZMA algorithm (option '--lzma')
|
||||||
* new options for compression tuning (e.g. '--brute')
|
|
||||||
* improved win32/pe compatibility
|
|
||||||
* direct ELF-to-memory decompression
|
|
||||||
* various bug fixes
|
|
||||||
|
|
||||||
|
|||||||
+13
-32
@@ -69,53 +69,34 @@ Tools needed to build/modify the UPX sources
|
|||||||
- A C++ compiler supporting inner classes, templates, exceptions
|
- A C++ compiler supporting inner classes, templates, exceptions
|
||||||
and RTTI.
|
and RTTI.
|
||||||
|
|
||||||
- GNU make 3.80 or better
|
- GNU make 3.80 or better (GNU make 3.81 recommened).
|
||||||
|
|
||||||
|
|
||||||
To compile the packer sources
|
To compile the packer sources
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
set the environment variable UCLDIR to point to your UCL installation, e.g.
|
set the environment variable UPX_UCLDIR to point to your
|
||||||
|
UCL installation, e.g.
|
||||||
|
|
||||||
set UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||||
export UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
export UPX_UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
||||||
|
|
||||||
then type
|
then type
|
||||||
|
|
||||||
make target=linux # linux
|
make
|
||||||
make target=djgpp2 # dos32 - djgpp2
|
|
||||||
make target=cygwin # win32 - cygwin 1.3.x
|
|
||||||
make target=mingw32 # win32 - mingw32
|
|
||||||
make target=no-cygwin # win32 - mingw32 as included in cygwin
|
|
||||||
|
|
||||||
|
|
||||||
If you want to modify the stub sources you'll also need
|
If you want to modify the stub sources you'll also need
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
- A68K - a 68000 macro assembler
|
- GNU make 3.81 or better
|
||||||
http://upx.sourceforge.net/download/tools/
|
http://savannah.gnu.org/projects/make/
|
||||||
|
|
||||||
- ASM5900 - a MIPS R3000 assembler
|
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
|
|
||||||
- djasm - an assembler for the djgpp stub
|
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
|
|
||||||
- nasm 0.98.39 - the Netwide Assembler
|
|
||||||
http://upx.sourceforge.net/download/tools/
|
|
||||||
http://sourceforge.net/projects/nasm/
|
|
||||||
|
|
||||||
- Perl & Python
|
- Perl & Python
|
||||||
|
|
||||||
- Certain versions of some i386-linux tools:
|
- A number of cross-assemblers and cross-compilers - precompiled
|
||||||
- gcc-2.95.3
|
binaries for i386-linux hosts are available from
|
||||||
- gcc-3.4.6
|
http://sourceforge.net/project/showfiles.php?group_id=2331
|
||||||
- binutils-2.16.1
|
|
||||||
|
|
||||||
- Other cross compilers targeted at the following architectures:
|
|
||||||
- arm-9tdmi-linux-gnu
|
|
||||||
- powerpc-750-linux-gnu
|
|
||||||
- x86_64-unknown-linux-gnu
|
|
||||||
|
|
||||||
|
|
||||||
Misc. notes
|
Misc. notes
|
||||||
@@ -130,8 +111,6 @@ Misc. notes
|
|||||||
stream.
|
stream.
|
||||||
- Use gcc extensions and other compiler specific stuff only through
|
- Use gcc extensions and other compiler specific stuff only through
|
||||||
macros.
|
macros.
|
||||||
- Keep in mind that it should be possible to build UPX on braindead
|
|
||||||
case insensitive file systems (FAT).
|
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -156,3 +135,5 @@ Patches/Contributions
|
|||||||
|
|
||||||
diff -uNr olddirectory newdirectory
|
diff -uNr olddirectory newdirectory
|
||||||
|
|
||||||
|
|
||||||
|
# vi:ts=4:et
|
||||||
|
|||||||
+45
-29
@@ -1,36 +1,51 @@
|
|||||||
|
#
|
||||||
|
# UPX doc Makefile - needs GNU make 3.80 or better
|
||||||
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
# internal make variables
|
||||||
|
comma := ,
|
||||||
|
empty :=
|
||||||
|
space := $(empty) $(empty)
|
||||||
|
tab := $(empty) $(empty)
|
||||||
|
|
||||||
|
# update $PATH for our special stub build tools
|
||||||
|
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||||
|
export PATH := $(HOME)/local/bin/bin-upx:$(PATH)
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||||
|
export PATH := $(HOME)/bin/bin-upx:$(PATH)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# //
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
top_srcdir = ..
|
top_srcdir = ..
|
||||||
|
|
||||||
PACKAGE = upx
|
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)
|
||||||
|
|
||||||
TRIMSPACE = cat
|
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||||
TRIMSPACE = sed -e 's/ *$$//'
|
DETAB2 := sed -e 's/$(tab)/ /g'
|
||||||
|
|
||||||
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
||||||
BUILT_SOURCES = upx.1 upx.doc upx.html
|
BUILT_SOURCES = upx.1 upx.doc upx.html
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
###
|
### targets
|
||||||
###
|
###
|
||||||
|
|
||||||
all: $(BUILT_SOURCES)
|
all: $(BUILT_SOURCES)
|
||||||
|
|
||||||
mostlyclean:
|
mostlyclean clean distclean maintainer-clean:
|
||||||
-rm -f $(BUILT_SOURCES) pod2htm*
|
rm -f $(BUILT_SOURCES) pod2htm*
|
||||||
|
|
||||||
clean: mostlyclean
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
|
|
||||||
maintainer-clean: distclean
|
|
||||||
|
|
||||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex .texi
|
|
||||||
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||||
|
|
||||||
@@ -39,26 +54,27 @@ maintainer-clean: distclean
|
|||||||
### rules
|
### rules
|
||||||
###
|
###
|
||||||
|
|
||||||
.pod.1:
|
.SUFFIXES: .1 .doc .html .man .pod .ps .tex
|
||||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.pod.html:
|
%.1 : %.pod
|
||||||
### pod2html $< | $(TRIMSPACE) > $@
|
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
||||||
pod2html --noindex $< | $(TRIMSPACE) > $@
|
|
||||||
@-rm -f pod2htm*
|
|
||||||
|
|
||||||
.pod.tex:
|
%.doc : %.pod
|
||||||
|
pod2text < $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.html : %.pod
|
||||||
|
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||||
|
@rm -f pod2htm*
|
||||||
|
|
||||||
|
%.man : %.1
|
||||||
|
nroff -man $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.ps : %.1
|
||||||
|
groff -man $< | $(RTRIM) > $@
|
||||||
|
|
||||||
|
%.tex : %.pod
|
||||||
pod2latex $<
|
pod2latex $<
|
||||||
|
|
||||||
.pod.doc:
|
|
||||||
pod2text < $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.1.man:
|
|
||||||
nroff -man $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
.1.ps:
|
|
||||||
groff -man $< | $(TRIMSPACE) > $@
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
### dependencies
|
### dependencies
|
||||||
|
|||||||
+18
-2
@@ -1,5 +1,5 @@
|
|||||||
Decompressing ELF Directly to Memory on Linux/x86
|
Decompressing ELF Directly to Memory on Linux/x86
|
||||||
Copyright 2000 John F. Reiser jreiser@BitWagon.com
|
Copyright (C) 2000-2006 John F. Reiser jreiser@BitWagon.com
|
||||||
|
|
||||||
References:
|
References:
|
||||||
<elf.h> definitions for the ELF file format
|
<elf.h> definitions for the ELF file format
|
||||||
@@ -17,7 +17,7 @@ program itself. So, the decompressor program (which contains the
|
|||||||
compressed version of the original executable) must have the same
|
compressed version of the original executable) must have the same
|
||||||
brk() as the original executable. So, the second PT_LOAD
|
brk() as the original executable. So, the second PT_LOAD
|
||||||
ELF "segment" of the compressed program is used only to set the brk(0).
|
ELF "segment" of the compressed program is used only to set the brk(0).
|
||||||
See src/p_lx_elf.cpp, function PackLinuxI386elf::patchLoader().
|
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
||||||
All of the decompressor's code, and all of the compressed image
|
All of the decompressor's code, and all of the compressed image
|
||||||
of the original executable, reside in the first PT_LOAD of the
|
of the original executable, reside in the first PT_LOAD of the
|
||||||
decompressor program.
|
decompressor program.
|
||||||
@@ -63,3 +63,19 @@ clear the free portion of the stack (to compensate for ld-linux.so.2
|
|||||||
assuming that its automatic stack variables are initialized to zero),
|
assuming that its automatic stack variables are initialized to zero),
|
||||||
and remove (all but 4 bytes of) the decompression program (and
|
and remove (all but 4 bytes of) the decompression program (and
|
||||||
compressed executable) from the address space.
|
compressed executable) from the address space.
|
||||||
|
|
||||||
|
Because the UPX runtime stub removes all traces of the compressed file
|
||||||
|
from the address space, then the Linux kernel erases the symlink
|
||||||
|
/proc/self/exe. Linux stores the pathname argument that was specified
|
||||||
|
to execve() immediately after the '\0' which terminates the character
|
||||||
|
string of the last environment variable [as of execve()]. This is true
|
||||||
|
for at least all Linux 2.6, 2.4, and 2.2 kernels. The pathname is not
|
||||||
|
"bound" to the file as strongly as /proc/self/exe (the file may be changed
|
||||||
|
without affecting the pathname), but the pathname does provide some
|
||||||
|
information. The pathname may be relative to the working directory,
|
||||||
|
so look before any chdir().
|
||||||
|
|
||||||
|
The Elf formats for Linux add an environment variable named " " [three
|
||||||
|
spaces] which saves the results of readlink("/proc/self/exe",,) before
|
||||||
|
the runtime stub unmaps all its pages. As of 2006-10-03 this works
|
||||||
|
for linux/elf386 and linux/ElfAMD.
|
||||||
|
|||||||
+27
-66
@@ -2,16 +2,8 @@ This documentation is written for those brave souls who want to
|
|||||||
understand and/or modify the UPX assembly stubs - the small snippets
|
understand and/or modify the UPX assembly stubs - the small snippets
|
||||||
that do the runtime decompression when a compressed program is started.
|
that do the runtime decompression when a compressed program is started.
|
||||||
|
|
||||||
So, how the runtime stub/loader generation works?
|
If you look at the C++ source files, you can find code fragments like
|
||||||
|
this:
|
||||||
You might have already noticed that for some file formats the loaders
|
|
||||||
are quite simple (linux/i386 & tos) while in the other cases the
|
|
||||||
loaders look very suspicious: they're full of `%ifdef's and contain
|
|
||||||
loads of cryptic comments like `__PERELOC2__'.
|
|
||||||
|
|
||||||
If you look at the C++ source files, however you can notice that these
|
|
||||||
comment strings (without the leading and trailing underscores) are used
|
|
||||||
in the following way:
|
|
||||||
|
|
||||||
addLoader("PEMAIN20",
|
addLoader("PEMAIN20",
|
||||||
ih.entry ? "PEDOJUMP" : "PERETURN",
|
ih.entry ? "PEDOJUMP" : "PERETURN",
|
||||||
@@ -19,71 +11,40 @@ in the following way:
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
Basically that's all you have to know: when you want to add a section
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
of assembly code to the runtime loader, you just write
|
|
||||||
|
|
||||||
l_foo.asm
|
and in the assembly files fragments like this:
|
||||||
---------
|
|
||||||
;__FOOBAR00__
|
|
||||||
|
|
||||||
|
section PEISDLL1
|
||||||
|
cmpb [esp + 8], 1
|
||||||
|
jnz reloc_end_jmp
|
||||||
|
|
||||||
|
section PEMAIN21
|
||||||
|
reloc_end_jmp:
|
||||||
|
|
||||||
|
section PERETURN
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
label1:
|
inc eax
|
||||||
jmps label1
|
ret 0x0C
|
||||||
|
section PEDOJUMP
|
||||||
|
jmp original_entry
|
||||||
|
|
||||||
;__FOOBARZZ__
|
Everything works as you would expect. If you want to add the code
|
||||||
|
fragment which is in `section PERETURN' to the runtime stub, then
|
||||||
p_foo.cpp
|
simply use `addLoader("PERETURN")' in the C++ source.
|
||||||
---------
|
|
||||||
|
|
||||||
addLoader("FOOBAR00", NULL);
|
|
||||||
|
|
||||||
This will add the assembly section starting from __FOOBAR00__ and ending
|
|
||||||
before __FOOBARZZ__ to the loader. You can add an %ifdef - %endif pair
|
|
||||||
before these comments if you wish - but these conditionals will NOT be
|
|
||||||
seen by the assembler, they are just syntactic sugar to make the code a
|
|
||||||
little bit more readable and understandable. (Note however, that only
|
|
||||||
%ifdefs which are started on the 1st column are removed by the upx
|
|
||||||
assembly preprocessor program, so you can still use preprocessor
|
|
||||||
conditionals if you wish - just write them starting from the 2nd
|
|
||||||
column.)
|
|
||||||
|
|
||||||
That's nice, you could say, but how cross section jumps and calls are
|
That's nice, you could say, but how cross section jumps and calls are
|
||||||
handled? Well, that is the nicest part of this stuff - they are handled
|
handled? Well, that is the nicest part of this stuff - they are handled
|
||||||
automatically. All you have to do is to add the required sections to the
|
automatically. All you have to do is to add the required sections to the
|
||||||
loader using `addLoader()' and the rest is done by upx. It will resolve
|
loader using `addLoader()' and the rest is done by upx. It will resolve
|
||||||
every conditional or unconditional jumps or subrutine calls for you.
|
every conditional or unconditional jumps or subroutine calls for you.
|
||||||
|
|
||||||
This functionality (we could say it's a simple linker) is achived by the
|
You can also use (undefined) symbols in the assembly for values that
|
||||||
assembly preprocessor (src/stub/scripts/app.pl) and a little C++ module
|
can only be computed during compression time (like `original_entry').
|
||||||
(src/linker.cpp). And of course NASM - the Netwide Assembler. You can
|
These symbols can be defined later in C++ using
|
||||||
see what's going on behind the scenes - just do:
|
|
||||||
|
|
||||||
cd src/stubs
|
linker->defineSymbol("xx", yy)
|
||||||
make maintainer-clean
|
|
||||||
make all
|
|
||||||
|
|
||||||
This will rebuild all the loaders - and keep the temporary files (*.as[xy])
|
This functionality (we could say it's a simple linker) is achived by
|
||||||
which are seen by the assembler.
|
compiling the assembly into an ELF object file which a little C++
|
||||||
|
module (src/linker.cpp) can interpret and work with.
|
||||||
Currently this loader/stub building method only works with ix86
|
|
||||||
assembly - both app.pl and linker.cpp heavily rely on this when dealing
|
|
||||||
with cross section references.
|
|
||||||
|
|
||||||
And finally some important features/requirements you should be aware of:
|
|
||||||
|
|
||||||
- as previously stated - preprocessor conditionals starting on the 1st
|
|
||||||
column are removed by app.pl
|
|
||||||
- sections are separated by comments in the form `;__X1234567__'
|
|
||||||
- jumps are recognized by searching for a word which starts with `j'
|
|
||||||
and followed by a label - this also means that `jmp short label1'
|
|
||||||
will NOT be recognized (but you can use a macro called `jmps' for it
|
|
||||||
by adding `%define jmps jmp short' to the beginning of the file)
|
|
||||||
- at the end of the file you need something like this
|
|
||||||
|
|
||||||
eof:
|
|
||||||
; __XTHEENDX__
|
|
||||||
section .data
|
|
||||||
dd -1
|
|
||||||
dw eof
|
|
||||||
|
|
||||||
That's all for now.
|
|
||||||
|
|||||||
+16
-11
@@ -699,19 +699,20 @@ nostalgic feelings of one of the authors.
|
|||||||
Packed programs will be byte-identical to the original after uncompression,
|
Packed programs will be byte-identical to the original after uncompression,
|
||||||
until further notice.
|
until further notice.
|
||||||
|
|
||||||
Maximum uncompressed size: ~1998848 bytes.
|
Maximum uncompressed size: ~1.89 / ~7.60 Mbytes.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
- UPX creates as default a 'CD-Rom only' PS1/PS2 compatible executable.
|
- UPX creates as default a suitable executable for CD-Mastering
|
||||||
For transfer between client/target use options below.
|
and console transfer. For a CD-Master main executable you could also try
|
||||||
|
the special option "--boot-only" as descriped below.
|
||||||
|
|
||||||
- Normally the packed files use the same memory areas like the uncompressed
|
- Normally the packed files use the same memory areas like the uncompressed
|
||||||
versions, so they will not override other memory areas while unpacking.
|
versions, so they will not override other memory areas while unpacking.
|
||||||
If this isn't possible UPX will abort showing a 'packed data overlap'
|
If this isn't possible UPX will abort showing a 'packed data overlap'
|
||||||
error. With the "--force" option UPX will set a few 'bytes higher' loading
|
error. With the "--force" option UPX will relocate the loading address
|
||||||
offset for the packed file, but this isn't a real problem if it is a
|
for the packed file, but this isn't a real problem if it is a single or
|
||||||
single or boot-only executable.
|
the main executable.
|
||||||
|
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
|
|
||||||
@@ -720,15 +721,19 @@ Extra options available for this executable format:
|
|||||||
the compression ratio in some cases, but usually
|
the compression ratio in some cases, but usually
|
||||||
the default method gives the best results anyway.
|
the default method gives the best results anyway.
|
||||||
|
|
||||||
--boot-only The format will only run from a CD and may slightly
|
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||||
improves the compression ratio. The decompression
|
|
||||||
routines are faster than default ones.
|
--8mb-ram PSone has 8 MB ram available [default: 2 MB]
|
||||||
But it cannot be used for host/client transfer !
|
|
||||||
|
--boot-only This format is for main exes and CD-Mastering only !
|
||||||
|
It may slightly improve the compression ratio,
|
||||||
|
decompression routines are faster than default ones.
|
||||||
|
But it cannot be used for console transfer !
|
||||||
|
|
||||||
--no-align This option disables CD mode 2 data sector format
|
--no-align This option disables CD mode 2 data sector format
|
||||||
alignment. May slightly improves the compression ratio,
|
alignment. May slightly improves the compression ratio,
|
||||||
but the compressed executable will not boot from a CD.
|
but the compressed executable will not boot from a CD.
|
||||||
Use it for client/target transfer only !
|
Use it for console transfer only !
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+58
-9
@@ -17,9 +17,18 @@ endif
|
|||||||
ifeq ($(CXX),)
|
ifeq ($(CXX),)
|
||||||
CXX = g++
|
CXX = g++
|
||||||
endif
|
endif
|
||||||
ifeq ($(CXX),g++)
|
ifeq ($(firstword $(CXX)),g++)
|
||||||
CXXFLAGS += -O2 -MMD
|
USE_GNUC ?= 1
|
||||||
|
endif
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
CXXFLAGS += -MMD
|
||||||
|
ifeq ($(DEBUG),1)
|
||||||
|
CXXFLAGS += -O0 -g
|
||||||
|
else
|
||||||
|
CXXFLAGS += -O2
|
||||||
|
endif
|
||||||
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
||||||
|
##CXXFLAGS += -Wshadow
|
||||||
endif
|
endif
|
||||||
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
||||||
CXXLD ?= $(CXX)
|
CXXLD ?= $(CXX)
|
||||||
@@ -28,16 +37,35 @@ exeext ?= .out
|
|||||||
libext ?= .a
|
libext ?= .a
|
||||||
objext ?= .o
|
objext ?= .o
|
||||||
|
|
||||||
# we need UCL and zlib - you can set envvar UCLDIR
|
|
||||||
ifneq ($(wildcard $(UCLDIR)/include/ucl/ucl.h),)
|
|
||||||
INCLUDES += -I$(UCLDIR)/include
|
|
||||||
LIBS += $(addprefix -L,$(dir $(wildcard $(UCLDIR)/libucl$(libext) $(UCLDIR)/src/.libs/libucl$(libext))))
|
|
||||||
endif
|
|
||||||
LIBS += -lucl -lz
|
|
||||||
|
|
||||||
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
||||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
||||||
|
|
||||||
|
# we need UCL and zlib - you can set envvar UPX_UCLDIR
|
||||||
|
ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),)
|
||||||
|
INCLUDES += -I$(UPX_UCLDIR)/include
|
||||||
|
LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext))))
|
||||||
|
endif
|
||||||
|
LIBS += -lucl -lz
|
||||||
|
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
|
||||||
|
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||||
|
DEFS += -DWITH_LZMA
|
||||||
|
INCLUDES += -I$(UPX_LZMADIR)
|
||||||
|
endif
|
||||||
|
# you should set envvar UPX_LUADIR to point to your unpacked lua-5.1.1.tar.gz
|
||||||
|
# [disabled for now]
|
||||||
|
ifneq ($(wildcard $(UPX_LUADIR)/src/lua.h),)
|
||||||
|
##DEFS += -DWITH_LUA
|
||||||
|
##upx_SOURCES_LUA := $(wildcard $(UPX_LUADIR)/src/*.c)
|
||||||
|
##upx_SOURCES_LUA := $(filter-out %lua.c, $(upx_SOURCES_LUA))
|
||||||
|
##upx_SOURCES_LUA := $(filter-out %luac.c, $(upx_SOURCES_LUA))
|
||||||
|
##upx_OBJECTS_LUA := $(notdir $(upx_SOURCES_LUA:.c=$(objext)))
|
||||||
|
##upx_OBJECTS_LUA := $(addprefix lua_,$(upx_OBJECTS_LUA))
|
||||||
|
##upx_OBJECTS += $(upx_OBJECTS_LUA)
|
||||||
|
else
|
||||||
|
##$(error please set UPX_LUADIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
all: upx$(exeext)
|
all: upx$(exeext)
|
||||||
|
|
||||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||||
@@ -48,6 +76,27 @@ upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
|||||||
%.o : %.cpp
|
%.o : %.cpp
|
||||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-cast-qual
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-non-virtual-dtor
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-shadow
|
||||||
|
compress_lzma$(objext) : CXXFLAGS += -Wno-unused
|
||||||
|
##compress_lzma$(objext) : CXXFLAGS += -Wno-error
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(strip $(upx_OBJECTS_LUA)),)
|
||||||
|
$(upx_OBJECTS_LUA) : lua_%.o : $(UPX_LUADIR)/src/%.c
|
||||||
|
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-align
|
||||||
|
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-qual
|
||||||
|
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-error
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
mostlyclean clean distclean maintainer-clean:
|
||||||
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
||||||
|
|
||||||
|
|||||||
+32
-3
@@ -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-2005 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2005 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -239,7 +239,7 @@ inline int get_le32_signed(const void *p)
|
|||||||
return sign_extend(v, 32);
|
return sign_extend(v, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_le64_signed(const void *p)
|
inline acc_int64l_t get_le64_signed(const void *p)
|
||||||
{
|
{
|
||||||
acc_int64l_t v = get_le64(p);
|
acc_int64l_t v = get_le64(p);
|
||||||
return sign_extend(v, 64);
|
return sign_extend(v, 64);
|
||||||
@@ -476,6 +476,35 @@ int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Provide namespaces and classes to abtract endianness policies.
|
||||||
|
//
|
||||||
|
// CTP - Compile-Time Polymorphism (templates)
|
||||||
|
// RTP - Run-Time Polymorphism (virtual functions)
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
namespace N_BELE_CTP {
|
||||||
|
class BEPolicy; class LEPolicy;
|
||||||
|
}
|
||||||
|
namespace N_BELE_RTP {
|
||||||
|
class AbstractPolicy;
|
||||||
|
class BEPolicy; class LEPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace N_BELE_CTP {
|
||||||
|
#define BELE_CTP 1
|
||||||
|
#include "bele_policy.h"
|
||||||
|
#undef BELE_CTP
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace N_BELE_RTP {
|
||||||
|
#define BELE_RTP 1
|
||||||
|
#include "bele_policy.h"
|
||||||
|
#undef BELE_RTP
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,273 @@
|
|||||||
|
/* bele_policy.h -- access memory in BigEndian and LittleEndian byte order
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UPX_BELE_H
|
||||||
|
# error "this is an internal include file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
// CTP - Compile-Time Polymorphism (templates)
|
||||||
|
# define V static inline
|
||||||
|
# define S static int __acc_cdecl_qsort
|
||||||
|
# define C
|
||||||
|
#elif defined(BELE_RTP)
|
||||||
|
// RTP - Run-Time Polymorphism (virtual functions)
|
||||||
|
# define V virtual
|
||||||
|
# define S virtual int
|
||||||
|
# define C const
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
struct AbstractPolicy
|
||||||
|
{
|
||||||
|
virtual inline ~AbstractPolicy() {}
|
||||||
|
V bool isBE() C = 0;
|
||||||
|
V bool isLE() C = 0;
|
||||||
|
|
||||||
|
V unsigned get16(const void *p) C = 0;
|
||||||
|
V unsigned get24(const void *p) C = 0;
|
||||||
|
V unsigned get32(const void *p) C = 0;
|
||||||
|
V acc_uint64l_t get64(const void *p) C = 0;
|
||||||
|
|
||||||
|
V void set16(void *p, unsigned v) C = 0;
|
||||||
|
V void set24(void *p, unsigned v) C = 0;
|
||||||
|
V void set32(void *p, unsigned v) C = 0;
|
||||||
|
V void set64(void *p, acc_uint64l_t v) C = 0;
|
||||||
|
|
||||||
|
V unsigned get16_signed(const void *p) C = 0;
|
||||||
|
V unsigned get24_signed(const void *p) C = 0;
|
||||||
|
V unsigned get32_signed(const void *p) C = 0;
|
||||||
|
V acc_uint64l_t get64_signed(const void *p) C = 0;
|
||||||
|
|
||||||
|
S u16_compare(const void *a, const void *b) C = 0;
|
||||||
|
S u24_compare(const void *a, const void *b) C = 0;
|
||||||
|
S u32_compare(const void *a, const void *b) C = 0;
|
||||||
|
S u64_compare(const void *a, const void *b) C = 0;
|
||||||
|
|
||||||
|
S u16_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
S u24_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
S u32_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
S u64_compare_signed(const void *a, const void *b) C = 0;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct BEPolicy
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
: public AbstractPolicy
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||||
|
enum { isBE = 1, isLE = 0 };
|
||||||
|
#elif defined(BELE_RTP)
|
||||||
|
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||||
|
V bool isBE() C { return CTP_Policy::isBE; }
|
||||||
|
V bool isLE() C { return CTP_Policy::isLE; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef BE16 U16;
|
||||||
|
typedef BE32 U32;
|
||||||
|
typedef BE64 U64;
|
||||||
|
|
||||||
|
V unsigned get16(const void *p) C
|
||||||
|
{ return get_be16(p); }
|
||||||
|
V unsigned get24(const void *p) C
|
||||||
|
{ return get_be24(p); }
|
||||||
|
V unsigned get32(const void *p) C
|
||||||
|
{ return get_be32(p); }
|
||||||
|
V acc_uint64l_t get64(const void *p) C
|
||||||
|
{ return get_be64(p); }
|
||||||
|
|
||||||
|
V void set16(void *p, unsigned v) C
|
||||||
|
{ set_be16(p, v); }
|
||||||
|
V void set24(void *p, unsigned v) C
|
||||||
|
{ set_be24(p, v); }
|
||||||
|
V void set32(void *p, unsigned v) C
|
||||||
|
{ set_be32(p, v); }
|
||||||
|
V void set64(void *p, acc_uint64l_t v) C
|
||||||
|
{ set_be64(p, v); }
|
||||||
|
|
||||||
|
V unsigned get16_signed(const void *p) C
|
||||||
|
{ return get_be16_signed(p); }
|
||||||
|
V unsigned get24_signed(const void *p) C
|
||||||
|
{ return get_be24_signed(p); }
|
||||||
|
V unsigned get32_signed(const void *p) C
|
||||||
|
{ return get_be32_signed(p); }
|
||||||
|
V acc_uint64l_t get64_signed(const void *p) C
|
||||||
|
{ return get_be64_signed(p); }
|
||||||
|
|
||||||
|
S u16_compare(const void *a, const void *b) C
|
||||||
|
{ return be16_compare(a, b); }
|
||||||
|
S u24_compare(const void *a, const void *b) C
|
||||||
|
{ return be24_compare(a, b); }
|
||||||
|
S u32_compare(const void *a, const void *b) C
|
||||||
|
{ return be32_compare(a, b); }
|
||||||
|
S u64_compare(const void *a, const void *b) C
|
||||||
|
{ return be64_compare(a, b); }
|
||||||
|
|
||||||
|
S u16_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be16_compare_signed(a, b); }
|
||||||
|
S u24_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be24_compare_signed(a, b); }
|
||||||
|
S u32_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be32_compare_signed(a, b); }
|
||||||
|
S u64_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return be64_compare_signed(a, b); }
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct LEPolicy
|
||||||
|
#if defined(BELE_RTP)
|
||||||
|
: public AbstractPolicy
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||||
|
enum { isBE = 0, isLE = 1 };
|
||||||
|
#elif defined(BELE_RTP)
|
||||||
|
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||||
|
V bool isBE() C { return CTP_Policy::isBE; }
|
||||||
|
V bool isLE() C { return CTP_Policy::isLE; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef LE16 U16;
|
||||||
|
typedef LE32 U32;
|
||||||
|
typedef LE64 U64;
|
||||||
|
|
||||||
|
V unsigned get16(const void *p) C
|
||||||
|
{ return get_le16(p); }
|
||||||
|
V unsigned get24(const void *p) C
|
||||||
|
{ return get_le24(p); }
|
||||||
|
V unsigned get32(const void *p) C
|
||||||
|
{ return get_le32(p); }
|
||||||
|
V acc_uint64l_t get64(const void *p) C
|
||||||
|
{ return get_le64(p); }
|
||||||
|
|
||||||
|
V void set16(void *p, unsigned v) C
|
||||||
|
{ set_le16(p, v); }
|
||||||
|
V void set24(void *p, unsigned v) C
|
||||||
|
{ set_le24(p, v); }
|
||||||
|
V void set32(void *p, unsigned v) C
|
||||||
|
{ set_le32(p, v); }
|
||||||
|
V void set64(void *p, acc_uint64l_t v) C
|
||||||
|
{ set_le64(p, v); }
|
||||||
|
|
||||||
|
V unsigned get16_signed(const void *p) C
|
||||||
|
{ return get_le16_signed(p); }
|
||||||
|
V unsigned get24_signed(const void *p) C
|
||||||
|
{ return get_le24_signed(p); }
|
||||||
|
V unsigned get32_signed(const void *p) C
|
||||||
|
{ return get_le32_signed(p); }
|
||||||
|
V acc_uint64l_t get64_signed(const void *p) C
|
||||||
|
{ return get_le64_signed(p); }
|
||||||
|
|
||||||
|
S u16_compare(const void *a, const void *b) C
|
||||||
|
{ return le16_compare(a, b); }
|
||||||
|
S u24_compare(const void *a, const void *b) C
|
||||||
|
{ return le24_compare(a, b); }
|
||||||
|
S u32_compare(const void *a, const void *b) C
|
||||||
|
{ return le32_compare(a, b); }
|
||||||
|
S u64_compare(const void *a, const void *b) C
|
||||||
|
{ return le64_compare(a, b); }
|
||||||
|
|
||||||
|
S u16_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le16_compare_signed(a, b); }
|
||||||
|
S u24_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le24_compare_signed(a, b); }
|
||||||
|
S u32_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le32_compare_signed(a, b); }
|
||||||
|
S u64_compare_signed(const void *a, const void *b) C
|
||||||
|
{ return le64_compare_signed(a, b); }
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
|
typedef BEPolicy HostPolicy;
|
||||||
|
#elif (ACC_ABI_LITTLE_ENDIAN)
|
||||||
|
typedef LEPolicy HostPolicy;
|
||||||
|
#else
|
||||||
|
# error "ACC_ABI_ENDIAN"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 /* UNUSED */
|
||||||
|
struct HostAlignedPolicy
|
||||||
|
{
|
||||||
|
#if defined(BELE_CTP)
|
||||||
|
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef acc_uint16e_t U16;
|
||||||
|
typedef acc_uint32e_t U32;
|
||||||
|
typedef acc_uint64l_t U64;
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#undef V
|
||||||
|
#undef S
|
||||||
|
#undef C
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=4:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
+2
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -72,7 +72,7 @@ static void print0(FILE *f, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+3
-3
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -124,7 +124,7 @@ static int set_fg(FILE *f, int fg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f,-1,-1);
|
init(f,-1,-1);
|
||||||
|
|||||||
+3
-3
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -58,7 +58,7 @@ static void print0(FILE *f, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+3
-3
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -295,7 +295,7 @@ static void print0(FILE *f, const char *ss)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static upx_bool intro(FILE *f)
|
static bool intro(FILE *f)
|
||||||
{
|
{
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
#if defined(USE_FRAMES)
|
#if defined(USE_FRAMES)
|
||||||
|
|||||||
+182
-11
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,21 +27,192 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined(WITH_NRV)
|
/*************************************************************************
|
||||||
# include "compress_nrv.ch"
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||||
|
{
|
||||||
|
if (len == 0)
|
||||||
|
return adler;
|
||||||
|
assert(buf != NULL);
|
||||||
|
#if 0
|
||||||
|
return adler32(adler, (const Bytef *) buf, len); // zlib
|
||||||
#elif defined(WITH_UCL)
|
#elif defined(WITH_UCL)
|
||||||
# define ALG_NRV2E
|
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||||
# define upx_adler32 upx_adler32
|
|
||||||
//# define upx_crc32 upx_crc32
|
|
||||||
# define upx_compress upx_compress
|
|
||||||
# define upx_decompress upx_decompress
|
|
||||||
# define upx_test_overlap upx_test_overlap
|
|
||||||
# include "compress.ch"
|
|
||||||
#else
|
#else
|
||||||
# error
|
# error
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 /* UNUSED */
|
||||||
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||||
|
{
|
||||||
|
if (len == 0)
|
||||||
|
return crc;
|
||||||
|
assert(buf != NULL);
|
||||||
|
#if 0
|
||||||
|
return crc32(crc, (const Bytef *) buf, len); // zlib
|
||||||
|
#elif defined(WITH_UCL)
|
||||||
|
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* UNUSED */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_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 r = UPX_E_ERROR;
|
||||||
|
upx_compress_result_t cresult_buffer;
|
||||||
|
|
||||||
|
assert(method > 0); assert(level > 0);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// set available bytes in dst
|
||||||
|
if (*dst_len == 0)
|
||||||
|
*dst_len = MemBuffer::getSizeForCompression(src_len);
|
||||||
|
#else
|
||||||
|
// force users to provide *dst_len
|
||||||
|
assert(*dst_len != 0);
|
||||||
|
#endif
|
||||||
|
// for UPX, we always require a reasonably sized outbut buffer
|
||||||
|
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
||||||
|
|
||||||
|
if (!cresult)
|
||||||
|
cresult = &cresult_buffer;
|
||||||
|
memset(cresult, 0, sizeof(*cresult));
|
||||||
|
#if 1
|
||||||
|
// debug
|
||||||
|
cresult->method = method;
|
||||||
|
cresult->level = level;
|
||||||
|
cresult->u_len = src_len;
|
||||||
|
cresult->c_len = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (method < 0) {
|
||||||
|
}
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
||||||
|
cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_nrv_compress(src, src_len, dst, dst_len,
|
||||||
|
cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
||||||
|
cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown compression method");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// debug
|
||||||
|
cresult->c_len = *dst_len;
|
||||||
|
#endif
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
|
assert(*dst_len > 0);
|
||||||
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
|
||||||
|
if (cresult && cresult->method == 0)
|
||||||
|
cresult = NULL;
|
||||||
|
|
||||||
|
if (method < 0) {
|
||||||
|
}
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_nrv_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
|
if (cresult && cresult->method == 0)
|
||||||
|
cresult = NULL;
|
||||||
|
|
||||||
|
assert(*dst_len > 0);
|
||||||
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
|
assert((int)overlap_overhead > 0);
|
||||||
|
|
||||||
|
if (method < 0) {
|
||||||
|
}
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
else if (M_IS_LZMA(method))
|
||||||
|
r = upx_lzma_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_nrv_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
|
r = upx_ucl_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/* compress.h --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UPX_COMPRESS_H
|
||||||
|
#define __UPX_COMPRESS_H
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
int upx_lzma_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_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(WITH_NRV)
|
||||||
|
int upx_nrv_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_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_nrv_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
int upx_ucl_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_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=4:et
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,450 @@
|
|||||||
|
/* compress_lzma.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#if !defined(WITH_LZMA)
|
||||||
|
extern int compress_lzma_dummy;
|
||||||
|
int compress_lzma_dummy = 0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
// INFO: the LZMA SDK is covered by a permissive license which allows
|
||||||
|
// using unmodified LZMA source code in UPX and the UPX stubs.
|
||||||
|
// See SPECIAL EXCEPTION below.
|
||||||
|
//
|
||||||
|
// Quoting from lzma-4.43/lzma.txt:
|
||||||
|
//
|
||||||
|
// LICENSE
|
||||||
|
// -------
|
||||||
|
//
|
||||||
|
// LZMA SDK is available under any of the following licenses:
|
||||||
|
//
|
||||||
|
// 1) GNU Lesser General Public License (GNU LGPL)
|
||||||
|
// 2) Common Public License (CPL)
|
||||||
|
// 3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
|
||||||
|
// 4) Proprietary license
|
||||||
|
//
|
||||||
|
// It means that you can select one of these four options and follow rules
|
||||||
|
// of that license.
|
||||||
|
//
|
||||||
|
// 1,2) GNU LGPL and CPL licenses are pretty similar and both these
|
||||||
|
// licenses are classified as
|
||||||
|
// - "Free software licenses" at http://www.gnu.org/
|
||||||
|
// - "OSI-approved" at http://www.opensource.org/
|
||||||
|
//
|
||||||
|
// 3) SPECIAL EXCEPTION
|
||||||
|
//
|
||||||
|
// Igor Pavlov, as the author of this code, expressly permits you
|
||||||
|
// to statically or dynamically link your code (or bind by name)
|
||||||
|
// to the files from LZMA SDK without subjecting your linked
|
||||||
|
// code to the terms of the CPL or GNU LGPL.
|
||||||
|
// Any modifications or additions to files from LZMA SDK, however,
|
||||||
|
// are subject to the GNU LGPL or CPL terms.
|
||||||
|
//
|
||||||
|
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
||||||
|
// while you keep LZMA SDK code unmodified.
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// cruft because of pseudo-COM layer
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#undef USE_LZMA_PROPERTIES
|
||||||
|
|
||||||
|
#undef MSDOS
|
||||||
|
#undef OS2
|
||||||
|
#undef _WIN32
|
||||||
|
#undef _WIN32_WCE
|
||||||
|
#undef COMPRESS_MF_MT
|
||||||
|
#undef _NO_EXCEPTIONS
|
||||||
|
#include "C/Common/MyInitGuid.h"
|
||||||
|
//#include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
||||||
|
#include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||||
|
|
||||||
|
namespace MyLzma {
|
||||||
|
|
||||||
|
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||||
|
{
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
const Byte *Data; size_t Size; size_t Pos;
|
||||||
|
void Init(const Byte *data, size_t size) {
|
||||||
|
Data = data; Size = size; Pos = 0;
|
||||||
|
}
|
||||||
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP InStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
|
{
|
||||||
|
UInt32 remain = Size - Pos;
|
||||||
|
if (size > remain) size = remain;
|
||||||
|
memmove(data, Data + Pos, size);
|
||||||
|
Pos += size;
|
||||||
|
if (processedSize != NULL) *processedSize = size;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||||
|
{
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
Byte *Data; size_t Size; size_t Pos; bool Overflow;
|
||||||
|
void Init(Byte *data, size_t size) {
|
||||||
|
Data = data; Size = size; Pos = 0; Overflow = false;
|
||||||
|
}
|
||||||
|
HRESULT WriteByte(Byte b) {
|
||||||
|
if (Pos >= Size) { Overflow = true; return E_FAIL; }
|
||||||
|
Data[Pos++] = b;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP OutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < size && Pos < Size; i++)
|
||||||
|
Data[Pos++] = ((const Byte *)data)[i];
|
||||||
|
if (processedSize != NULL) *processedSize = i;
|
||||||
|
if (i != size) { Overflow = true; return E_FAIL; }
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
||||||
|
{
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||||
|
upx_callback_p cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||||
|
{
|
||||||
|
if (cb && cb->nprogress)
|
||||||
|
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
int upx_lzma_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_parm,
|
||||||
|
upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_LZMA);
|
||||||
|
assert(level > 0); assert(cresult != NULL);
|
||||||
|
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
HRESULT rh;
|
||||||
|
lzma_compress_result_t *res = &cresult->result_lzma;
|
||||||
|
|
||||||
|
MyLzma::InStreamRam is; is.AddRef();
|
||||||
|
MyLzma::OutStreamRam os; os.AddRef();
|
||||||
|
is.Init(src, src_len);
|
||||||
|
os.Init(dst, *dst_len);
|
||||||
|
|
||||||
|
MyLzma::ProgressInfo progress; progress.AddRef();
|
||||||
|
progress.cb = cb;
|
||||||
|
|
||||||
|
NCompress::NLZMA::CEncoder enc;
|
||||||
|
const PROPID propIDs[7] = {
|
||||||
|
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||||
|
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||||
|
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||||
|
NCoderPropID::kDictionarySize, // 3
|
||||||
|
NCoderPropID::kAlgorithm, // 4 _fastmode
|
||||||
|
NCoderPropID::kNumFastBytes, // 5
|
||||||
|
NCoderPropID::kMatchFinderCycles // 6
|
||||||
|
};
|
||||||
|
PROPVARIANT pr[7];
|
||||||
|
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;
|
||||||
|
|
||||||
|
// setup defaults
|
||||||
|
pr[0].uintVal = 2; // 0..4
|
||||||
|
pr[1].uintVal = 0; // 0..4
|
||||||
|
pr[2].uintVal = 3; // 0..8
|
||||||
|
pr[3].uintVal = 1024 * 1024;
|
||||||
|
pr[4].uintVal = 2;
|
||||||
|
pr[5].uintVal = 64; // 5..
|
||||||
|
pr[6].uintVal = 0;
|
||||||
|
#if 0
|
||||||
|
// DEBUG - set sizes so that we use a maxmimum amount of stack.
|
||||||
|
// These settings cause res->num_probs == 3147574, i.e. we will
|
||||||
|
// need about 6 MB of stack during runtime decompression.
|
||||||
|
pr[1].uintVal = 4;
|
||||||
|
pr[2].uintVal = 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FIXME: tune these settings according to level
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
pr[3].uintVal = 256 * 1024;
|
||||||
|
pr[4].uintVal = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
pr[3].uintVal = 8 * 1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
pr[3].uintVal = src_len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit dictionary size
|
||||||
|
if (pr[3].uintVal > src_len)
|
||||||
|
pr[3].uintVal = src_len;
|
||||||
|
|
||||||
|
// limit num_probs
|
||||||
|
if (cconf_parm && cconf_parm->conf_lzma.max_num_probs)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
unsigned n = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
|
||||||
|
if (n <= cconf_parm->conf_lzma.max_num_probs)
|
||||||
|
break;
|
||||||
|
if (pr[1].uintVal > pr[2].uintVal)
|
||||||
|
{
|
||||||
|
if (pr[1].uintVal == 0)
|
||||||
|
goto error;
|
||||||
|
pr[1].uintVal -= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pr[2].uintVal == 0)
|
||||||
|
goto error;
|
||||||
|
pr[2].uintVal -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res->pos_bits = pr[0].uintVal;
|
||||||
|
res->lit_pos_bits = pr[1].uintVal;
|
||||||
|
res->lit_context_bits = pr[2].uintVal;
|
||||||
|
res->dict_size = pr[3].uintVal;
|
||||||
|
//res->num_probs = LzmaGetNumProbs(&s.Properties));
|
||||||
|
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||||
|
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
|
|
||||||
|
#ifndef _NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (enc.SetCoderProperties(propIDs, pr, 7) != S_OK)
|
||||||
|
goto error;
|
||||||
|
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||||
|
goto error;
|
||||||
|
if (os.Overflow) {
|
||||||
|
//r = UPX_E_OUTPUT_OVERRUN;
|
||||||
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
assert(os.Pos == 5);
|
||||||
|
#if defined(USE_LZMA_PROPERTIES)
|
||||||
|
os.Pos = 1;
|
||||||
|
#else
|
||||||
|
os.Pos = 0;
|
||||||
|
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
|
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||||
|
os.WriteByte((t << 3) | res->pos_bits);
|
||||||
|
os.WriteByte((res->lit_pos_bits << 4) | (res->lit_context_bits));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rh = enc.Code(&is, &os, NULL, NULL, &progress);
|
||||||
|
|
||||||
|
#ifndef _NO_EXCEPTIONS
|
||||||
|
} catch(...) { return UPX_E_OUT_OF_MEMORY; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(is.Pos <= src_len);
|
||||||
|
assert(os.Pos <= *dst_len);
|
||||||
|
if (rh == E_OUTOFMEMORY)
|
||||||
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
|
else if (os.Overflow)
|
||||||
|
{
|
||||||
|
assert(os.Pos == *dst_len);
|
||||||
|
//r = UPX_E_OUTPUT_OVERRUN;
|
||||||
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
}
|
||||||
|
else if (rh == S_OK)
|
||||||
|
{
|
||||||
|
assert(is.Pos == src_len);
|
||||||
|
r = UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
*dst_len = os.Pos;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "C/Common/Alloc.cpp"
|
||||||
|
#include "C/Common/CRC.cpp"
|
||||||
|
//#include "C/7zip/Common/InBuffer.cpp"
|
||||||
|
#include "C/7zip/Common/OutBuffer.cpp"
|
||||||
|
#include "C/7zip/Common/StreamUtils.cpp"
|
||||||
|
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
|
||||||
|
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||||
|
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||||
|
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||||
|
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||||
|
#undef RC_NORMALIZE
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// decompress
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#undef _LZMA_IN_CB
|
||||||
|
#undef _LZMA_OUT_READ
|
||||||
|
#undef _LZMA_PROB32
|
||||||
|
#undef _LZMA_LOC_OPT
|
||||||
|
#include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
||||||
|
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||||
|
|
||||||
|
int upx_lzma_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_LZMA);
|
||||||
|
// see res->num_probs above
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||||
|
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||||
|
|
||||||
|
CLzmaDecoderState s; memset(&s, 0, sizeof(s));
|
||||||
|
SizeT src_out = 0, dst_out = 0;
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
int rh;
|
||||||
|
|
||||||
|
#if defined(USE_LZMA_PROPERTIES)
|
||||||
|
if (src_len < 2)
|
||||||
|
goto error;
|
||||||
|
rh = LzmaDecodeProperties(&s.Properties, src, src_len);
|
||||||
|
if (rh != 0)
|
||||||
|
goto error;
|
||||||
|
src += 1; src_len -= 1;
|
||||||
|
#else
|
||||||
|
if (src_len < 3)
|
||||||
|
goto error;
|
||||||
|
s.Properties.pb = src[0] & 7;
|
||||||
|
s.Properties.lp = (src[1] >> 4);
|
||||||
|
s.Properties.lc = src[1] & 15;
|
||||||
|
if (s.Properties.pb >= 5) goto error;
|
||||||
|
if (s.Properties.lp >= 5) goto error;
|
||||||
|
if (s.Properties.lc >= 9) goto error;
|
||||||
|
// extra
|
||||||
|
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
|
||||||
|
src += 2; src_len -= 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cresult)
|
||||||
|
{
|
||||||
|
assert(cresult->method == method);
|
||||||
|
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_context_bits == (unsigned) s.Properties.lc);
|
||||||
|
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||||
|
}
|
||||||
|
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||||
|
if (!s.Probs)
|
||||||
|
{
|
||||||
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
||||||
|
assert(src_out <= src_len);
|
||||||
|
assert(dst_out <= *dst_len);
|
||||||
|
if (rh == 0)
|
||||||
|
{
|
||||||
|
r = UPX_E_OK;
|
||||||
|
if (src_out != src_len)
|
||||||
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
*dst_len = dst_out;
|
||||||
|
free(s.Probs);
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// test_overlap
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult )
|
||||||
|
{
|
||||||
|
assert(method == M_LZMA);
|
||||||
|
|
||||||
|
// FIXME - implement this
|
||||||
|
// Note that Packer::verifyOverlappingDecompression() will
|
||||||
|
// verify the final result in any case.
|
||||||
|
UNUSED(buf);
|
||||||
|
|
||||||
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
|
//printf("upx_lzma_test_overlap: %d\n", overlap_overhead);
|
||||||
|
if ((int)overlap_overhead >= 256)
|
||||||
|
return UPX_E_OK;
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WITH_LZMA */
|
||||||
|
/*
|
||||||
|
vi:ts=4:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/* compress.ch --
|
/* compress_ucl.cpp --
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,6 +26,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
#if !defined(WITH_UCL)
|
||||||
|
extern int compress_ucl_dummy;
|
||||||
|
int compress_ucl_dummy = 0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if 1 && !defined(UCL_USE_ASM) && (ACC_ARCH_I386)
|
||||||
|
# if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_WATCOMC)
|
||||||
|
# define UCL_USE_ASM
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if defined(UCL_NO_ASM)
|
||||||
|
# undef UCL_USE_ASM
|
||||||
|
#endif
|
||||||
|
#if defined(ACC_CFG_NO_UNALIGNED)
|
||||||
|
# undef UCL_USE_ASM
|
||||||
|
#endif
|
||||||
#if 1 && defined(UCL_USE_ASM)
|
#if 1 && defined(UCL_USE_ASM)
|
||||||
# include <ucl/ucl_asm.h>
|
# include <ucl/ucl_asm.h>
|
||||||
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
||||||
@@ -44,115 +62,122 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_adler32)
|
static int convert_errno_from_ucl(int r)
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
|
||||||
{
|
{
|
||||||
if (len == 0)
|
switch (r)
|
||||||
return adler;
|
{
|
||||||
assert(buf != NULL);
|
case UCL_E_OK: return UPX_E_OK;
|
||||||
return ucl_adler32(adler, (const ucl_bytep)buf, len);
|
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;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(upx_crc32)
|
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (state != -1 && state != 3) return;
|
||||||
return crc;
|
upx_callback_p cb = (upx_callback_p) user;
|
||||||
assert(buf != NULL);
|
if (cb && cb->nprogress)
|
||||||
return ucl_crc32(crc, (const ucl_bytep)buf, len);
|
cb->nprogress(cb, a, b);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_compress)
|
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
upx_callback_p cb_parm,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
|
||||||
upx_progress_callback_t *cb,
|
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const struct upx_compress_config_t *conf_parm,
|
const upx_compress_config_t *cconf_parm,
|
||||||
upx_uintp result )
|
upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
struct upx_compress_config_t conf;
|
int r;
|
||||||
upx_uint result_buffer[16];
|
assert(level > 0); assert(cresult != NULL);
|
||||||
int r = UPX_E_ERROR;
|
|
||||||
|
|
||||||
assert(level > 0);
|
ucl_progress_callback_t cb;
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
cb.callback = 0;
|
||||||
if (conf_parm)
|
cb.user = NULL;
|
||||||
conf = *conf_parm; // struct copy
|
if (cb_parm && cb_parm->nprogress) {
|
||||||
if (!result)
|
cb.callback = wrap_nprogress_ucl;
|
||||||
result = result_buffer;
|
cb.user = cb_parm;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucl_compress_config_t cconf;
|
||||||
|
memset(&cconf, 0xff, sizeof(cconf));
|
||||||
|
if (cconf_parm)
|
||||||
|
cconf = cconf_parm->conf_ucl; // struct copy
|
||||||
|
|
||||||
|
ucl_uint *res = cresult->result_ucl.result;
|
||||||
// assume no info available - fill in worst case results
|
// assume no info available - fill in worst case results
|
||||||
//result[0] = 1; // min_offset_found - NOT USED
|
//res[0] = 1; // min_offset_found - NOT USED
|
||||||
result[1] = src_len - 1; // max_offset_found
|
res[1] = src_len - 1; // max_offset_found
|
||||||
//result[2] = 2; // min_match_found - NOT USED
|
//res[2] = 2; // min_match_found - NOT USED
|
||||||
result[3] = src_len - 1; // max_match_found
|
res[3] = src_len - 1; // max_match_found
|
||||||
//result[4] = 1; // min_run_found - NOT USED
|
//res[4] = 1; // min_run_found - NOT USED
|
||||||
result[5] = src_len; // max_run_found
|
res[5] = src_len; // max_run_found
|
||||||
result[6] = 1; // first_offset_found
|
res[6] = 1; // first_offset_found
|
||||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||||
|
|
||||||
// prepare bit-buffer settings
|
// prepare bit-buffer settings
|
||||||
conf.bb_endian = 0;
|
cconf.bb_endian = 0;
|
||||||
conf.bb_size = 0;
|
cconf.bb_size = 0;
|
||||||
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
|
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
|
||||||
{
|
{
|
||||||
static const unsigned char sizes[3] = {32, 8, 16};
|
static const unsigned char sizes[3] = {32, 8, 16};
|
||||||
conf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// optimize compression parms
|
// optimize compression parms
|
||||||
if (level <= 3 && conf.max_offset == UPX_UINT_MAX)
|
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
conf.max_offset = 8*1024-1;
|
cconf.max_offset = 8*1024-1;
|
||||||
else if (level == 4 && conf.max_offset == UPX_UINT_MAX)
|
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
conf.max_offset = 32*1024-1;
|
cconf.max_offset = 32*1024-1;
|
||||||
|
|
||||||
if M_IS_NRV2B(method)
|
if M_IS_NRV2B(method)
|
||||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
else if M_IS_NRV2D(method)
|
else if M_IS_NRV2D(method)
|
||||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
else if M_IS_NRV2E(method)
|
else if M_IS_NRV2E(method)
|
||||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||||
cb, level, &conf, result);
|
&cb, level, &cconf, res);
|
||||||
#endif
|
else {
|
||||||
#if 0 /*{*/
|
|
||||||
else if M_IS_CL1B(method)
|
|
||||||
r = cl1b_compress(src, src_len, dst, dst_len,
|
|
||||||
cb, level, &conf, result);
|
|
||||||
#endif /*}*/
|
|
||||||
else
|
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_compress */
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_decompress)
|
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
int method,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
const upx_compress_result_t *cresult )
|
||||||
int method )
|
|
||||||
{
|
{
|
||||||
int r = UPX_E_ERROR;
|
int r;
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
@@ -174,7 +199,6 @@ int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
|||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
@@ -184,40 +208,26 @@ int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
|||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if 0 /*{*/
|
|
||||||
case M_CL1B_8:
|
|
||||||
r = cl1b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE16:
|
|
||||||
r = cl1b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE32:
|
|
||||||
r = cl1b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
#endif /*}*/
|
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
break;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_decompress */
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(upx_test_overlap)
|
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned* dst_len,
|
||||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
int method,
|
||||||
upx_uint src_len, upx_uintp dst_len,
|
const upx_compress_result_t *cresult )
|
||||||
int method )
|
|
||||||
{
|
{
|
||||||
int r = UPX_E_ERROR;
|
int r;
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
@@ -239,7 +249,6 @@ int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
|||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#if defined(ALG_NRV2E)
|
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
@@ -249,29 +258,17 @@ int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
|||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if 0 /*{*/
|
|
||||||
case M_CL1B_8:
|
|
||||||
r = cl1b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE16:
|
|
||||||
r = cl1b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
case M_CL1B_LE32:
|
|
||||||
r = cl1b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
|
||||||
break;
|
|
||||||
#endif /*}*/
|
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
break;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* upx_test_overlap */
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WITH_UCL */
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
*/
|
*/
|
||||||
+130
-33
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -144,35 +144,27 @@
|
|||||||
# undef __unix
|
# undef __unix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(WITH_UCL)
|
#if !defined(WITH_UCL)
|
||||||
# define WITH_UCL 1
|
# define WITH_UCL 1
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_UCL)
|
#if 0 && !defined(WITH_LZMA)
|
||||||
# include <ucl/uclconf.h>
|
# define WITH_LZMA 1
|
||||||
# include <ucl/ucl.h>
|
|
||||||
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010200L)
|
|
||||||
# error "please upgrade your UCL installation"
|
|
||||||
#endif
|
#endif
|
||||||
# if !defined(UPX_UINT_MAX)
|
#if defined(UPX_OFFICIAL_BUILD)
|
||||||
# define UPX_UINT_MAX UCL_UINT_MAX
|
# if !defined(WITH_LZMA) || !defined(WITH_NRV) || !defined(WITH_UCL)
|
||||||
# define upx_uint ucl_uint
|
# error
|
||||||
# define upx_voidp ucl_voidp
|
|
||||||
# define upx_uintp ucl_uintp
|
|
||||||
# define upx_byte ucl_byte
|
|
||||||
# define upx_bytep ucl_bytep
|
|
||||||
# define upx_bool ucl_bool
|
|
||||||
# define upx_compress_config_t ucl_compress_config_t
|
|
||||||
# define upx_progress_callback_t ucl_progress_callback_t
|
|
||||||
# define UPX_E_OK UCL_E_OK
|
|
||||||
# define UPX_E_ERROR UCL_E_ERROR
|
|
||||||
# define UPX_E_OUT_OF_MEMORY UCL_E_OUT_OF_MEMORY
|
|
||||||
# define __UPX_CDECL __UCL_CDECL
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_NRV)
|
#if defined(WITH_NRV)
|
||||||
# include <nrv/nrvconf.h>
|
# include <nrv/nrvconf.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WITH_UCL)
|
||||||
|
# include <ucl/uclconf.h>
|
||||||
|
# include <ucl/ucl.h>
|
||||||
|
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010300L)
|
||||||
|
# error "please upgrade your UCL installation"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
#if !defined(__UPX_CHECKER)
|
#if !defined(__UPX_CHECKER)
|
||||||
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
||||||
# define __UPX_CHECKER
|
# define __UPX_CHECKER
|
||||||
@@ -182,6 +174,94 @@
|
|||||||
# error "UINT_MAX"
|
# error "UINT_MAX"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define upx_byte unsigned char
|
||||||
|
#define upx_bytep upx_byte *
|
||||||
|
#define UPX_E_OK (0)
|
||||||
|
#define UPX_E_ERROR (-1)
|
||||||
|
#define UPX_E_OUT_OF_MEMORY (-2)
|
||||||
|
#define UPX_E_NOT_COMPRESSIBLE (-3)
|
||||||
|
#define UPX_E_INPUT_OVERRUN (-4)
|
||||||
|
#define UPX_E_OUTPUT_OVERRUN (-5)
|
||||||
|
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
|
||||||
|
#define UPX_E_EOF_NOT_FOUND (-7)
|
||||||
|
#define UPX_E_INPUT_NOT_CONSUMED (-8)
|
||||||
|
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
|
||||||
|
#define UPX_E_INVALID_ARGUMENT (-10)
|
||||||
|
|
||||||
|
struct upx_callback_t;
|
||||||
|
#define upx_callback_p upx_callback_t *
|
||||||
|
typedef void* (__acc_cdecl *upx_alloc_func_t)
|
||||||
|
(upx_callback_p self, unsigned items, unsigned size);
|
||||||
|
typedef void (__acc_cdecl *upx_free_func_t)
|
||||||
|
(upx_callback_p self, void* ptr);
|
||||||
|
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||||
|
(upx_callback_p, unsigned, unsigned);
|
||||||
|
|
||||||
|
struct upx_callback_t
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
upx_alloc_func_t nalloc;
|
||||||
|
upx_free_func_t nfree;
|
||||||
|
#endif
|
||||||
|
upx_progress_func_t nprogress;
|
||||||
|
void * user1;
|
||||||
|
#if 0
|
||||||
|
unsigned user2;
|
||||||
|
unsigned user3;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct lzma_compress_config_t
|
||||||
|
{
|
||||||
|
unsigned max_num_probs;
|
||||||
|
#if 0
|
||||||
|
unsigned pos_bits; // pb
|
||||||
|
unsigned lit_pos_bits; // lp
|
||||||
|
unsigned lit_context_bits; // lc
|
||||||
|
unsigned dict_size;
|
||||||
|
unsigned mf_passes;
|
||||||
|
#endif
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define upx_compress_config_p upx_compress_config_t *
|
||||||
|
struct upx_compress_config_t
|
||||||
|
{
|
||||||
|
lzma_compress_config_t conf_lzma;
|
||||||
|
ucl_compress_config_t conf_ucl;
|
||||||
|
void reset() {
|
||||||
|
conf_lzma.reset();
|
||||||
|
memset(&conf_ucl, 0xff, sizeof(conf_ucl));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct lzma_compress_result_t
|
||||||
|
{
|
||||||
|
unsigned pos_bits; // pb
|
||||||
|
unsigned lit_pos_bits; // lp
|
||||||
|
unsigned lit_context_bits; // lc
|
||||||
|
unsigned dict_size;
|
||||||
|
unsigned num_probs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ucl_compress_result_t
|
||||||
|
{
|
||||||
|
ucl_uint result[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct upx_compress_result_t
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
// debug
|
||||||
|
int method, level;
|
||||||
|
unsigned u_len, c_len;
|
||||||
|
#endif
|
||||||
|
lzma_compress_result_t result_lzma;
|
||||||
|
ucl_compress_result_t result_ucl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// system includes
|
// system includes
|
||||||
@@ -417,6 +497,8 @@ inline void operator delete[](void *p)
|
|||||||
|
|
||||||
|
|
||||||
// compression methods - DO NOT CHANGE
|
// compression methods - DO NOT CHANGE
|
||||||
|
#define M_SKIP (-2)
|
||||||
|
#define M_END (-1)
|
||||||
#define M_NRV2B_LE32 2
|
#define M_NRV2B_LE32 2
|
||||||
#define M_NRV2B_8 3
|
#define M_NRV2B_8 3
|
||||||
#define M_NRV2B_LE16 4
|
#define M_NRV2B_LE16 4
|
||||||
@@ -429,11 +511,13 @@ inline void operator delete[](void *p)
|
|||||||
#define M_CL1B_LE32 11
|
#define M_CL1B_LE32 11
|
||||||
#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_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
|
||||||
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
|
||||||
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
|
||||||
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
||||||
|
#define M_IS_LZMA(x) ((x) == M_LZMA)
|
||||||
|
|
||||||
|
|
||||||
// Executable formats. Note: big endian types are >= 128.
|
// Executable formats. Note: big endian types are >= 128.
|
||||||
@@ -459,6 +543,11 @@ inline void operator delete[](void *p)
|
|||||||
#define UPX_F_LINUX_ELFI_i386 20
|
#define UPX_F_LINUX_ELFI_i386 20
|
||||||
#define UPX_F_WINCE_ARM_PE 21
|
#define UPX_F_WINCE_ARM_PE 21
|
||||||
#define UPX_F_LINUX_ELF64_AMD 22
|
#define UPX_F_LINUX_ELF64_AMD 22
|
||||||
|
#define UPX_F_LINUX_ELF32_ARMLE 23
|
||||||
|
|
||||||
|
#define UPX_F_BSD_i386 24
|
||||||
|
#define UPX_F_BSD_ELF_i386 25
|
||||||
|
#define UPX_F_BSD_SH_i386 26
|
||||||
|
|
||||||
#define UPX_F_PLAIN_TEXT 127
|
#define UPX_F_PLAIN_TEXT 127
|
||||||
|
|
||||||
@@ -466,6 +555,7 @@ inline void operator delete[](void *p)
|
|||||||
#define UPX_F_SOLARIS_SPARC 130
|
#define UPX_F_SOLARIS_SPARC 130
|
||||||
#define UPX_F_MACH_PPC32 131
|
#define UPX_F_MACH_PPC32 131
|
||||||
#define UPX_F_LINUX_ELFPPC32 132
|
#define UPX_F_LINUX_ELFPPC32 132
|
||||||
|
#define UPX_F_LINUX_ELF32_ARMBE 133
|
||||||
|
|
||||||
|
|
||||||
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
||||||
@@ -488,6 +578,11 @@ inline void operator delete[](void *p)
|
|||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
|
|
||||||
|
// classes
|
||||||
|
class ElfLinker;
|
||||||
|
typedef ElfLinker Linker;
|
||||||
|
|
||||||
|
|
||||||
// main.cpp
|
// main.cpp
|
||||||
extern const char *progname;
|
extern const char *progname;
|
||||||
void init_options(struct options_t *o);
|
void init_options(struct options_t *o);
|
||||||
@@ -547,18 +642,20 @@ void show_version(int);
|
|||||||
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);
|
||||||
|
|
||||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
upx_progress_callback_t *cb,
|
upx_callback_p cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const struct upx_compress_config_t *conf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_uintp result );
|
upx_compress_result_t *cresult );
|
||||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method );
|
int method,
|
||||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
const upx_compress_result_t *cresult );
|
||||||
upx_uint src_len, upx_uintp dst_len,
|
int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||||
int method );
|
unsigned src_len, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
+3
-3
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,7 +117,7 @@ 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);
|
||||||
upx_bool (*intro)(FILE *f);
|
bool (*intro)(FILE *f);
|
||||||
}
|
}
|
||||||
console_t;
|
console_t;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
-8
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -387,7 +387,7 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
|
|||||||
// 24-bit ARM calltrick ("naive")
|
// 24-bit ARM calltrick ("naive")
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CT24ARM(f, cond, addvalue, get, set) \
|
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
||||||
upx_byte *b = f->buf; \
|
upx_byte *b = f->buf; \
|
||||||
upx_byte *b_end = b + f->buf_len - 4; \
|
upx_byte *b_end = b + f->buf_len - 4; \
|
||||||
do { \
|
do { \
|
||||||
@@ -404,24 +404,59 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
#define ARMCT_COND (((b[3] & 0x0f) == 0x0b))
|
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
|
||||||
|
|
||||||
static int f_ct24arm_le(Filter *f)
|
static int f_ct24arm_le(Filter *f)
|
||||||
{
|
{
|
||||||
CT24ARM(f, ARMCT_COND, a / 4 + f->addvalue, get_le24, set_le24)
|
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u_ct24arm_le(Filter *f)
|
static int u_ct24arm_le(Filter *f)
|
||||||
{
|
{
|
||||||
CT24ARM(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s_ct24arm_le(Filter *f)
|
static int s_ct24arm_le(Filter *f)
|
||||||
{
|
{
|
||||||
CT24ARM(f, ARMCT_COND, a + f->addvalue, get_le24, set_dummy)
|
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CT24ARM
|
#undef CT24ARM_LE
|
||||||
|
|
||||||
|
#define CT24ARM_BE(f, cond, addvalue, get, set) \
|
||||||
|
upx_byte *b = f->buf; \
|
||||||
|
upx_byte *b_end = b + f->buf_len - 4; \
|
||||||
|
do { \
|
||||||
|
if (cond) \
|
||||||
|
{ \
|
||||||
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
|
f->lastcall = a; \
|
||||||
|
set(1+b, get(1+b) + (addvalue)); \
|
||||||
|
f->calls++; \
|
||||||
|
} \
|
||||||
|
b += 4; \
|
||||||
|
} while (b < b_end); \
|
||||||
|
if (f->lastcall) f->lastcall += 4; \
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b))
|
||||||
|
|
||||||
|
static int f_ct24arm_be(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int u_ct24arm_be(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int s_ct24arm_be(Filter *f)
|
||||||
|
{
|
||||||
|
CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CT24ARM_BE
|
||||||
#undef ARMCT_COND
|
#undef ARMCT_COND
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+2
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2004-2005 John F. Reiser
|
Copyright (C) 2004-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -226,6 +226,7 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
|
|
||||||
// 24-bit calltrick for arm
|
// 24-bit calltrick for arm
|
||||||
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
||||||
|
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
||||||
|
|
||||||
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
||||||
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||||
|
|||||||
+8
-5
@@ -196,7 +196,8 @@ void show_help(int x)
|
|||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --all-methods try all available compression methods\n"
|
" --all-methods try all available compression methods\n"
|
||||||
" --8-bit uses 8 bit size compression [default: 32 bit]\n"
|
" --8-bit uses 8 bit size compression [default: 32 bit]\n"
|
||||||
" --console-run enables client/host transfer compatibility\n"
|
" --8mb-ram 8 megabyte memory limit [default: 2 mb]\n"
|
||||||
|
" --boot-only disables client/host transfer compatibility\n"
|
||||||
" --no-align don't align to 2048 bytes [enables: --console-run]\n"
|
" --no-align don't align to 2048 bytes [enables: --console-run]\n"
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
@@ -342,21 +343,23 @@ void show_version(int x)
|
|||||||
FILE *f = stdout;
|
FILE *f = stdout;
|
||||||
UNUSED(x);
|
UNUSED(x);
|
||||||
|
|
||||||
#if (0 && ACC_CC_GNUC)
|
|
||||||
fprintf(f,"upx %s (gcc 0x%06lx)\n", UPX_VERSION_STRING, ACC_CC_GNUC);
|
|
||||||
#else
|
|
||||||
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
|
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
|
||||||
#endif
|
|
||||||
#if defined(WITH_NRV)
|
#if defined(WITH_NRV)
|
||||||
fprintf(f,"NRV data compression library %s\n", nrv_version_string());
|
fprintf(f,"NRV data compression library %s\n", nrv_version_string());
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_UCL)
|
#if defined(WITH_UCL)
|
||||||
fprintf(f,"UCL data compression library %s\n", ucl_version_string());
|
fprintf(f,"UCL data compression library %s\n", ucl_version_string());
|
||||||
|
#endif
|
||||||
|
#if 0 && defined(WITH_LZMA)
|
||||||
|
fprintf(f,"LZMA SDK version ???\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf(f,"Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
|
fprintf(f,"Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
|
||||||
fprintf(f,"Copyright (C) 1996-2006 Laszlo Molnar\n");
|
fprintf(f,"Copyright (C) 1996-2006 Laszlo Molnar\n");
|
||||||
fprintf(f,"Copyright (C) 2000-2006 John F. Reiser\n");
|
fprintf(f,"Copyright (C) 2000-2006 John F. Reiser\n");
|
||||||
fprintf(f,"Copyright (C) 2002-2006 Jens Medoch\n");
|
fprintf(f,"Copyright (C) 2002-2006 Jens Medoch\n");
|
||||||
|
#if defined(WITH_LZMA)
|
||||||
|
fprintf(f,"Copyright (C) 1999-2006 Igor Pavlov\n");
|
||||||
|
#endif
|
||||||
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
|
|||||||
+609
-171
@@ -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-2005 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2005 Laszlo Molnar
|
Copyright (C) 1996-2006 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,108 +29,278 @@
|
|||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
class LinkerLabel
|
static int hex(unsigned char c)
|
||||||
{
|
|
||||||
enum { LINKER_MAX_LABEL_LEN = 32 };
|
|
||||||
char label[LINKER_MAX_LABEL_LEN + 1];
|
|
||||||
|
|
||||||
public:
|
|
||||||
unsigned set(const char *l)
|
|
||||||
{
|
|
||||||
strncpy(label, l, sizeof(label));
|
|
||||||
return strlen(label) + 1;
|
|
||||||
}
|
|
||||||
operator const char *() const { return label; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Linker::section
|
|
||||||
{
|
|
||||||
int istart;
|
|
||||||
int ostart;
|
|
||||||
int len;
|
|
||||||
LinkerLabel name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Linker::jump
|
|
||||||
{
|
|
||||||
int pos;
|
|
||||||
int len;
|
|
||||||
int toffs;
|
|
||||||
LinkerLabel tsect;
|
|
||||||
};
|
|
||||||
|
|
||||||
Linker::Linker(const void *pdata, int plen, int pinfo)
|
|
||||||
{
|
|
||||||
iloader = new char[(ilen = plen) + 8192];
|
|
||||||
memcpy(iloader,pdata,plen);
|
|
||||||
oloader = new char[plen];
|
|
||||||
olen = 0;
|
|
||||||
align_hack = 0;
|
|
||||||
align_offset = 0;
|
|
||||||
info = pinfo;
|
|
||||||
njumps = nsections = frozen = 0;
|
|
||||||
jumps = new jump[200];
|
|
||||||
#define NSECTIONS 550
|
|
||||||
sections = new section[NSECTIONS];
|
|
||||||
|
|
||||||
char *p = iloader + info;
|
|
||||||
while (get32(p) != (unsigned)(-1))
|
|
||||||
{
|
|
||||||
if (get32(p))
|
|
||||||
{
|
|
||||||
p += sections[nsections].name.set(p);
|
|
||||||
sections[nsections].istart = get32(p);
|
|
||||||
sections[nsections++].ostart = -1;
|
|
||||||
p += 4;
|
|
||||||
assert(nsections < NSECTIONS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
for (l = get32(p+4) - 1; iloader[l] == 0; l--)
|
|
||||||
;
|
|
||||||
|
|
||||||
jumps[njumps].pos = l+1;
|
|
||||||
jumps[njumps].len = get32(p+4)-jumps[njumps].pos;
|
|
||||||
p += 8 + jumps[njumps].tsect.set(p + 8);
|
|
||||||
jumps[njumps++].toffs = get32(p);
|
|
||||||
p += 4;
|
|
||||||
assert(njumps < 200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ic;
|
|
||||||
for (ic = 0; ic < nsections - 1; ic++)
|
|
||||||
sections[ic].len = sections[ic+1].istart - sections[ic].istart;
|
|
||||||
sections[ic].len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Linker::~Linker()
|
|
||||||
{
|
|
||||||
delete [] iloader;
|
|
||||||
delete [] oloader;
|
|
||||||
delete [] jumps;
|
|
||||||
delete [] sections;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Linker::setLoaderAlignOffset(int offset)
|
|
||||||
{
|
|
||||||
align_offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hex(char c)
|
|
||||||
{
|
{
|
||||||
return (c & 0xf) + (c > '9' ? 9 : 0);
|
return (c & 0xf) + (c > '9' ? 9 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Linker::addSection(const char *psect)
|
static bool update_capacity(unsigned size, unsigned *capacity)
|
||||||
{
|
{
|
||||||
if (psect[0] == 0)
|
if (size < *capacity)
|
||||||
return olen;
|
return false;
|
||||||
char *begin = strdup(psect);
|
if (*capacity == 0)
|
||||||
|
*capacity = 16;
|
||||||
|
while (size >= *capacity)
|
||||||
|
*capacity *= 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a) :
|
||||||
|
name(strdup(n)), output(NULL), size(s), offset(0), align(a), next(NULL)
|
||||||
|
{
|
||||||
|
assert(name);
|
||||||
|
input = malloc(s + 1);
|
||||||
|
assert(input);
|
||||||
|
memcpy(input, i, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Section::~Section()
|
||||||
|
{
|
||||||
|
free(name);
|
||||||
|
free(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Symbol::Symbol(const char *n, Section *s, unsigned o) :
|
||||||
|
name(strdup(n)), section(s), offset(o)
|
||||||
|
{
|
||||||
|
assert(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Symbol::~Symbol()
|
||||||
|
{
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t,
|
||||||
|
const Symbol *v, unsigned a) :
|
||||||
|
section(s), offset(o), type(t), value(v), add(a)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinker::preprocessSections(char *start, const char *end)
|
||||||
|
{
|
||||||
|
nsections = 0;
|
||||||
|
while (start < end)
|
||||||
|
{
|
||||||
|
char name[1024];
|
||||||
|
unsigned offset, size, align;
|
||||||
|
|
||||||
|
char *nextl = strchr(start, '\n');
|
||||||
|
assert(nextl != NULL);
|
||||||
|
|
||||||
|
if (sscanf(start, "%*d %1023s %x %*d %*d %x 2**%d",
|
||||||
|
name, &size, &offset, &align) == 4)
|
||||||
|
{
|
||||||
|
char *n = strstr(start, name);
|
||||||
|
n[strlen(name)] = 0;
|
||||||
|
addSection(n, input + offset, size, align);
|
||||||
|
|
||||||
|
//printf("section %s preprocessed\n", n);
|
||||||
|
}
|
||||||
|
start = nextl + 1;
|
||||||
|
}
|
||||||
|
addSection("*ABS*", NULL, 0, 0);
|
||||||
|
addSection("*UND*", NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::preprocessSymbols(char *start, const char *end)
|
||||||
|
{
|
||||||
|
nsymbols = 0;
|
||||||
|
while (start < end)
|
||||||
|
{
|
||||||
|
char section[1024];
|
||||||
|
char symbol[1024];
|
||||||
|
unsigned offset;
|
||||||
|
|
||||||
|
char *nextl = strchr(start, '\n');
|
||||||
|
assert(nextl != NULL);
|
||||||
|
|
||||||
|
if (sscanf(start, "%x%*8c %1024s %*x %1023s",
|
||||||
|
&offset, section, symbol) == 3)
|
||||||
|
{
|
||||||
|
char *s = strstr(start, symbol);
|
||||||
|
s[strlen(symbol)] = 0;
|
||||||
|
|
||||||
|
if (strcmp(section, "*UND*") == 0)
|
||||||
|
offset = 0xdeaddead;
|
||||||
|
addSymbol(s, section, offset);
|
||||||
|
|
||||||
|
//printf("symbol %s preprocessed o=%x\n", s, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = nextl + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::preprocessRelocations(char *start, const char *end)
|
||||||
|
{
|
||||||
|
char sect[1024];
|
||||||
|
Section *section = NULL;
|
||||||
|
|
||||||
|
nrelocations = 0;
|
||||||
|
while (start < end)
|
||||||
|
{
|
||||||
|
if (sscanf(start, "RELOCATION RECORDS FOR [%[^]]", sect) == 1)
|
||||||
|
section = findSection(sect);
|
||||||
|
|
||||||
|
unsigned offset;
|
||||||
|
char type[100];
|
||||||
|
char symbol[1024];
|
||||||
|
|
||||||
|
char *nextl = strchr(start, '\n');
|
||||||
|
assert(nextl != NULL);
|
||||||
|
|
||||||
|
if (sscanf(start, "%x %99s %1023s",
|
||||||
|
&offset, type, symbol) == 3)
|
||||||
|
{
|
||||||
|
char *t = strstr(start, type);
|
||||||
|
t[strlen(type)] = 0;
|
||||||
|
|
||||||
|
unsigned add = 0;
|
||||||
|
if (char *p = strstr(symbol, "+0x"))
|
||||||
|
{
|
||||||
|
// Beware: sscanf("0xfffffffffffffffc", "%x", &add) ==> -1 == add
|
||||||
|
// because conversion stops after 32 bits for a non-long.
|
||||||
|
// Also, glibc-2.3.5 has a bug: even using "%lx" still gives -1 instead of -4.
|
||||||
|
long addend;
|
||||||
|
*p = 0; // terminate the symbol name
|
||||||
|
p+=3;
|
||||||
|
if ('f'==p[0] && 0==strncmp(p, "ffffffff", 8)) {
|
||||||
|
p+=8; // workaround a bug in glibc-2.3.5
|
||||||
|
}
|
||||||
|
sscanf(p, "%lx", &addend);
|
||||||
|
add = (unsigned)addend;
|
||||||
|
}
|
||||||
|
|
||||||
|
addRelocation(section->name, offset, t, symbol, add);
|
||||||
|
|
||||||
|
//printf("relocation %s %x preprocessed\n", section->name, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = nextl + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Section *ElfLinker::findSection(const char *name) const
|
||||||
|
{
|
||||||
|
for (unsigned ic = 0; ic < nsections; ic++)
|
||||||
|
if (strcmp(sections[ic]->name, name) == 0)
|
||||||
|
return sections[ic];
|
||||||
|
|
||||||
|
printf("unknown section %s\n", name);
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name) /*const*/
|
||||||
|
{
|
||||||
|
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||||
|
if (strcmp(symbols[ic]->name, name) == 0)
|
||||||
|
return symbols[ic];
|
||||||
|
|
||||||
|
// FIXME: this should be a const method !
|
||||||
|
if ('*' == name[0]) // *ABS*
|
||||||
|
return addSymbol(name, name, 0);
|
||||||
|
|
||||||
|
printf("unknown symbol %s\n", name);
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
||||||
|
unsigned offset)
|
||||||
|
{
|
||||||
|
if (update_capacity(nsymbols, &nsymbols_capacity))
|
||||||
|
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
||||||
|
assert(symbols != NULL);
|
||||||
|
Symbol *sym = new Symbol(name, findSection(section), offset);
|
||||||
|
symbols[nsymbols++] = sym;
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned off,
|
||||||
|
const char *type, const char *symbol,
|
||||||
|
unsigned add)
|
||||||
|
{
|
||||||
|
if (update_capacity(nrelocations, &nrelocations_capacity))
|
||||||
|
relocations = static_cast<Relocation **>(realloc(relocations, (nrelocations_capacity) * sizeof(Relocation *)));
|
||||||
|
assert(relocations != NULL);
|
||||||
|
Relocation *rel = new Relocation(findSection(section), off,
|
||||||
|
type, findSymbol(symbol), add);
|
||||||
|
relocations[nrelocations++] = rel;
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::ElfLinker() :
|
||||||
|
frozen(false), input(NULL), output(NULL), head(NULL), tail(NULL),
|
||||||
|
sections(NULL), symbols(NULL), relocations(NULL),
|
||||||
|
nsections(0), nsections_capacity(0),
|
||||||
|
nsymbols(0), nsymbols_capacity(0),
|
||||||
|
nrelocations(0), nrelocations_capacity(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ElfLinker::~ElfLinker()
|
||||||
|
{
|
||||||
|
delete [] input;
|
||||||
|
delete [] output;
|
||||||
|
|
||||||
|
unsigned ic;
|
||||||
|
for (ic = 0; ic < nsections; ic++)
|
||||||
|
delete sections[ic];
|
||||||
|
free(sections);
|
||||||
|
for (ic = 0; ic < nsymbols; ic++)
|
||||||
|
delete symbols[ic];
|
||||||
|
free(symbols);
|
||||||
|
for (ic = 0; ic < nrelocations; ic++)
|
||||||
|
delete relocations[ic];
|
||||||
|
free(relocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::init(const void *pdata, int plen)
|
||||||
|
{
|
||||||
|
upx_byte *i = new upx_byte[plen + 1];
|
||||||
|
memcpy(i, pdata, plen);
|
||||||
|
input = i;
|
||||||
|
inputlen = plen;
|
||||||
|
|
||||||
|
output = new upx_byte[plen];
|
||||||
|
outputlen = 0;
|
||||||
|
|
||||||
|
int pos = find(input, plen, "Sections:", 9);
|
||||||
|
assert(pos != -1);
|
||||||
|
char *psections = pos + (char *) input;
|
||||||
|
|
||||||
|
char *psymbols = strstr(psections, "SYMBOL TABLE:");
|
||||||
|
assert(psymbols != NULL);
|
||||||
|
|
||||||
|
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR");
|
||||||
|
assert(prelocs != NULL);
|
||||||
|
input[plen] = 0;
|
||||||
|
|
||||||
|
preprocessSections(psections, psymbols);
|
||||||
|
preprocessSymbols(psymbols, prelocs);
|
||||||
|
preprocessRelocations(prelocs, (char*) input + inputlen);
|
||||||
|
addLoader("*UND*");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::setLoaderAlignOffset(int phase)
|
||||||
|
{
|
||||||
|
//assert(phase & 0);
|
||||||
|
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ElfLinker::addLoader(const char *sname)
|
||||||
|
{
|
||||||
|
assert(!frozen);
|
||||||
|
if (sname[0] == 0)
|
||||||
|
return outputlen;
|
||||||
|
|
||||||
|
char *begin = strdup(sname);
|
||||||
char *end = begin + strlen(begin);
|
char *end = begin + strlen(begin);
|
||||||
for (char *sect = begin; sect < end; )
|
for (char *sect = begin; sect < end; )
|
||||||
{
|
{
|
||||||
@@ -143,100 +313,368 @@ int Linker::addSection(const char *psect)
|
|||||||
|
|
||||||
if (*sect == '+') // alignment
|
if (*sect == '+') // alignment
|
||||||
{
|
{
|
||||||
if (sect[1] == '0')
|
assert(tail);
|
||||||
align_hack = olen + align_offset;
|
if (unsigned l = (hex(sect[2]) - tail->offset - tail->size)
|
||||||
else
|
% hex(sect[1]))
|
||||||
{
|
{
|
||||||
unsigned j = hex(sect[1]);
|
alignCode(l);
|
||||||
j = (hex(sect[2]) - ((olen + align_offset) - align_hack) ) % j;
|
tail->size += l;
|
||||||
memset(oloader+olen, (sect[3] == 'C' ? 0x90 : 0), j);
|
outputlen += l;
|
||||||
olen += j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ic;
|
Section *section = findSection(sect);
|
||||||
for (ic = 0; ic < nsections; ic++)
|
if (section->align) {
|
||||||
if (strcmp(sect, sections[ic].name) == 0)
|
unsigned const v = ~0u << section->align;
|
||||||
{
|
assert(tail);
|
||||||
memcpy(oloader+olen,iloader+sections[ic].istart,sections[ic].len);
|
if (unsigned const l = ~v & -(tail->offset + tail->size)) {
|
||||||
sections[ic].ostart = olen;
|
alignCode(l);
|
||||||
olen += sections[ic].len;
|
tail->size += l;
|
||||||
break;
|
outputlen += l;
|
||||||
}
|
}
|
||||||
if (ic == nsections)
|
}
|
||||||
printf("%s", sect);
|
memcpy(output + outputlen, section->input, section->size);
|
||||||
assert(ic != nsections);
|
section->output = output + outputlen;
|
||||||
|
outputlen += section->size;
|
||||||
|
//printf("section added: %s\n", sect);
|
||||||
|
|
||||||
|
if (head)
|
||||||
|
{
|
||||||
|
tail->next = section;
|
||||||
|
section->offset = tail->offset + tail->size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
head = section;
|
||||||
|
tail = section;
|
||||||
}
|
}
|
||||||
sect += strlen(sect) + 1;
|
sect += strlen(sect) + 1;
|
||||||
}
|
}
|
||||||
free(begin);
|
free(begin);
|
||||||
return olen;
|
return outputlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElfLinker::addSection(const char *sname, const void *sdata, int slen, int align)
|
||||||
void Linker::addSection(const char *sname, const void *sdata, unsigned len)
|
|
||||||
{
|
{
|
||||||
// add a new section - can be used for adding stuff like ident or header
|
assert(!frozen);
|
||||||
sections[nsections].name.set(sname);
|
if (update_capacity(nsections, &nsections_capacity))
|
||||||
sections[nsections].istart = ilen;
|
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
|
||||||
sections[nsections].len = len;
|
assert(sections);
|
||||||
sections[nsections++].ostart = olen;
|
Section *sec = new Section(sname, sdata, slen, align);
|
||||||
assert(nsections < NSECTIONS);
|
sections[nsections++] = sec;
|
||||||
memcpy(iloader+ilen,sdata,len);
|
//return sec;
|
||||||
ilen += len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElfLinker::freeze()
|
||||||
const char *Linker::getLoader(int *llen)
|
|
||||||
{
|
{
|
||||||
if (!frozen)
|
if (frozen)
|
||||||
{
|
return;
|
||||||
int ic,jc,kc;
|
|
||||||
for (ic = 0; ic < njumps; ic++)
|
|
||||||
{
|
|
||||||
for (jc = 0; jc < nsections-1; jc++)
|
|
||||||
if (jumps[ic].pos >= sections[jc].istart
|
|
||||||
&& jumps[ic].pos < sections[jc+1].istart)
|
|
||||||
break;
|
|
||||||
assert(jc!=nsections-1);
|
|
||||||
if (sections[jc].ostart < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (kc = 0; kc < nsections-1; kc++)
|
frozen = true;
|
||||||
if (strcmp(jumps[ic].tsect,sections[kc].name) == 0)
|
|
||||||
break;
|
|
||||||
assert(kc!=nsections-1);
|
|
||||||
|
|
||||||
int offs = sections[kc].ostart+jumps[ic].toffs -
|
|
||||||
(jumps[ic].pos+jumps[ic].len -
|
|
||||||
sections[jc].istart+sections[jc].ostart);
|
|
||||||
|
|
||||||
if (jumps[ic].len == 1)
|
|
||||||
assert(-128 <= offs && offs <= 127);
|
|
||||||
|
|
||||||
set32(&offs,offs);
|
|
||||||
memcpy(oloader+sections[jc].ostart+jumps[ic].pos-sections[jc].istart,&offs,jumps[ic].len);
|
|
||||||
}
|
|
||||||
frozen=1;
|
|
||||||
}
|
|
||||||
if (llen) *llen = olen;
|
|
||||||
return oloader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ElfLinker::getSection(const char *sname, int *slen)
|
||||||
int Linker::getSection(const char *name, int *slen) const
|
|
||||||
{
|
|
||||||
if (!frozen)
|
|
||||||
return -1;
|
|
||||||
for (int ic = 0; ic < nsections; ic++)
|
|
||||||
if (strcmp(name, sections[ic].name) == 0)
|
|
||||||
{
|
{
|
||||||
|
assert(frozen);
|
||||||
|
Section *section = findSection(sname);
|
||||||
if (slen)
|
if (slen)
|
||||||
*slen = sections[ic].len;
|
*slen = section->size;
|
||||||
return sections[ic].ostart;
|
return section->output - output;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
upx_byte *ElfLinker::getLoader(int *llen)
|
||||||
|
{
|
||||||
|
assert(frozen);
|
||||||
|
|
||||||
|
if (llen)
|
||||||
|
*llen = outputlen;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::relocate()
|
||||||
|
{
|
||||||
|
assert(frozen);
|
||||||
|
|
||||||
|
for (unsigned ic = 0; ic < nrelocations; ic++)
|
||||||
|
{
|
||||||
|
Relocation *rel = relocations[ic];
|
||||||
|
if (rel->section->output == NULL)
|
||||||
|
continue;
|
||||||
|
if (rel->value->section->output == NULL)
|
||||||
|
{
|
||||||
|
printf("can not apply reloc '%s:%x' without section '%s'\n",
|
||||||
|
rel->section->name, rel->offset,
|
||||||
|
rel->value->section->name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(rel->value->section->name, "*UND*") == 0 &&
|
||||||
|
rel->value->offset == 0xdeaddead)
|
||||||
|
{
|
||||||
|
printf("undefined symbol '%s' referenced\n", rel->value->name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
unsigned value = rel->value->section->offset +
|
||||||
|
rel->value->offset + rel->add;
|
||||||
|
upx_byte *location = rel->section->output + rel->offset;
|
||||||
|
|
||||||
|
relocate1(rel, location, value, rel->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::defineSymbol(const char *name, unsigned value)
|
||||||
|
{
|
||||||
|
Symbol *symbol = findSymbol(name);
|
||||||
|
if (strcmp(symbol->section->name, "*UND*") == 0) // for undefined symbols
|
||||||
|
symbol->offset = value;
|
||||||
|
else if (strcmp(symbol->section->name, name) == 0) // for sections
|
||||||
|
{
|
||||||
|
for (Section *section = symbol->section; section; section = section->next)
|
||||||
|
{
|
||||||
|
assert(section->offset < value);
|
||||||
|
section->offset = value;
|
||||||
|
value += section->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("symbol '%s' already defined\n", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// debugging support
|
||||||
|
void ElfLinker::dumpSymbols(FILE *fp) const
|
||||||
|
{
|
||||||
|
if (fp == NULL)
|
||||||
|
fp = stdout;
|
||||||
|
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||||
|
{
|
||||||
|
Symbol *symbol = symbols[ic];
|
||||||
|
fprintf(fp, "%-20s 0x%08x | %-20s 0x%08x\n",
|
||||||
|
symbol->name, symbol->offset, symbol->section->name, symbol->section->offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ElfLinker::getSymbolOffset(const char *name) const
|
||||||
|
{
|
||||||
|
assert(frozen);
|
||||||
|
Symbol *symbol = const_cast<ElfLinker *>(this)->findSymbol(name);
|
||||||
|
if (symbol->section->output == NULL)
|
||||||
|
return 0xdeaddead;
|
||||||
|
return symbol->section->offset + symbol->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::alignWithByte(unsigned len, upx_byte b)
|
||||||
|
{
|
||||||
|
memset(output + outputlen, b, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
|
||||||
|
unsigned, const char *)
|
||||||
|
{
|
||||||
|
printf("unknown relocation type '%s\n", rel->type);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// ElfLinker arch subclasses
|
||||||
|
// FIXME: add more displacment overflow checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_X86_64_", 9))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 9;
|
||||||
|
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type, "8") == 0)
|
||||||
|
{
|
||||||
|
int displ = (signed char) *location + (int) value;
|
||||||
|
if (displ < -128 || displ > 127)
|
||||||
|
{
|
||||||
|
printf("target out of range (%d) in reloc %s:%x\n",
|
||||||
|
displ, rel->section->name, rel->offset);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*location += value;
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + value);
|
||||||
|
else if (strcmp(type, "32") == 0)
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_be24(1+ location, get_be24(1+ location) + value / 4);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||||
|
{
|
||||||
|
set_be32(location, get_be32(location) + value);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
value += ((get_be16(location) & 0x7ff) << 12);
|
||||||
|
value += (get_be16(location + 2) & 0x7ff) << 1;
|
||||||
|
|
||||||
|
set_be16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||||
|
set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||||
|
|
||||||
|
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||||
|
//set_be32(location, get_be32(location) + value / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_le24(location, get_le24(location) + value / 4);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||||
|
{
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
value += ((get_le16(location) & 0x7ff) << 12);
|
||||||
|
value += (get_le16(location + 2) & 0x7ff) << 1;
|
||||||
|
|
||||||
|
set_le16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||||
|
set_le16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||||
|
|
||||||
|
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||||
|
//set_le32(location, get_le32(location) + value / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerM68k::alignCode(unsigned len)
|
||||||
|
{
|
||||||
|
assert((len & 1) == 0);
|
||||||
|
assert((outputlen & 1) == 0);
|
||||||
|
for (unsigned i = 0; i < len; i += 2)
|
||||||
|
set_be16(output + outputlen + i, 0x4e71); // "nop"
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_68K_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 2;
|
||||||
|
}
|
||||||
|
if (strcmp(type, "8") == 0)
|
||||||
|
*location += value;
|
||||||
|
else if (strcmp(type, "16") == 0)
|
||||||
|
set_be16(location, get_be16(location) + value);
|
||||||
|
else if (strcmp(type, "32") == 0)
|
||||||
|
set_be32(location, get_be32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_PPC_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
if (strncmp(type, "REL", 3) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: more relocs
|
||||||
|
|
||||||
|
// Note that original (*location).displ is ignored.
|
||||||
|
if (strcmp(type, "24") == 0) {
|
||||||
|
if (3& value) {
|
||||||
|
printf("unaligned word diplacement");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// FIXME: displacment overflow?
|
||||||
|
set_be32(location, (0xfc000003 & get_be32(location)) +
|
||||||
|
(0x03fffffc & value));
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "14") == 0) {
|
||||||
|
if (3& value) {
|
||||||
|
printf("unaligned word diplacement");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// FIXME: displacment overflow?
|
||||||
|
set_be32(location, (0xffff0003 & get_be32(location)) +
|
||||||
|
(0x0000fffc & value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strncmp(type, "R_386_", 6))
|
||||||
|
return super::relocate1(rel, location, value, type);
|
||||||
|
type += 6;
|
||||||
|
|
||||||
|
int range_check = 0;
|
||||||
|
if (strncmp(type, "PC", 2) == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
type += 2;
|
||||||
|
range_check = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type, "8") == 0)
|
||||||
|
{
|
||||||
|
int displ = (signed char) *location + (int) value;
|
||||||
|
if (range_check && (displ < -128 || displ > 127)) {
|
||||||
|
printf("target out of range (%d) in reloc %s:%x\n",
|
||||||
|
displ, rel->section->name, rel->offset);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*location += value;
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + value);
|
||||||
|
else if (strcmp(type, "32") == 0)
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+157
-47
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -30,64 +30,174 @@
|
|||||||
#define __UPX_LINKER_H
|
#define __UPX_LINKER_H
|
||||||
|
|
||||||
|
|
||||||
class Linker
|
/*************************************************************************
|
||||||
|
// ElfLinker
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
class ElfLinker : private nocopy
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
Linker(const void *pdata, int plen, int pinfo);
|
|
||||||
virtual ~Linker();
|
|
||||||
int addSection(const char *sect);
|
|
||||||
void addSection(const char *sname, const void *sdata, unsigned len);
|
|
||||||
const char *getLoader(int *llen);
|
|
||||||
int getSection(const char *name, int *slen) const;
|
|
||||||
int getLoaderSize() const { return olen; }
|
|
||||||
void setLoaderAlignOffset(int phase);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// little endian
|
struct Section;
|
||||||
virtual unsigned get32(const void *b) const { return get_le32(b); }
|
struct Symbol;
|
||||||
virtual void set32(void *b, unsigned v) const { set_le32(b, v); }
|
struct Relocation;
|
||||||
|
|
||||||
private:
|
bool frozen; // FIXME: can we remove this ?
|
||||||
struct section;
|
|
||||||
struct jump;
|
|
||||||
|
|
||||||
char *iloader, *oloader;
|
upx_byte *input;
|
||||||
int ilen, olen;
|
int inputlen;
|
||||||
int info;
|
upx_byte *output;
|
||||||
jump *jumps;
|
int outputlen;
|
||||||
int njumps;
|
|
||||||
section *sections;
|
|
||||||
int nsections;
|
|
||||||
int frozen;
|
|
||||||
int align_hack;
|
|
||||||
int align_offset;
|
|
||||||
|
|
||||||
private:
|
Section *head;
|
||||||
// disable copy and assignment
|
Section *tail;
|
||||||
Linker(const Linker &); // {}
|
|
||||||
Linker& operator= (const Linker &); // { return *this; }
|
Section **sections;
|
||||||
|
Symbol **symbols;
|
||||||
|
Relocation **relocations;
|
||||||
|
|
||||||
|
unsigned nsections;
|
||||||
|
unsigned nsections_capacity;
|
||||||
|
unsigned nsymbols;
|
||||||
|
unsigned nsymbols_capacity;
|
||||||
|
unsigned nrelocations;
|
||||||
|
unsigned nrelocations_capacity;
|
||||||
|
|
||||||
|
void preprocessSections(char *start, const char *end);
|
||||||
|
void preprocessSymbols(char *start, const char *end);
|
||||||
|
void preprocessRelocations(char *start, const char *end);
|
||||||
|
Section *findSection(const char *name) const;
|
||||||
|
Symbol *findSymbol(const char *name) /*const*/;
|
||||||
|
|
||||||
|
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
|
||||||
|
Relocation *addRelocation(const char *section, unsigned off, const char *type,
|
||||||
|
const char *symbol, unsigned add);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ElfLinker();
|
||||||
|
virtual ~ElfLinker();
|
||||||
|
|
||||||
|
virtual void init(const void *pdata, int plen);
|
||||||
|
virtual void setLoaderAlignOffset(int phase);
|
||||||
|
virtual int addLoader(const char *sname);
|
||||||
|
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
|
||||||
|
virtual void freeze();
|
||||||
|
virtual int getSection(const char *sname, int *slen=NULL);
|
||||||
|
virtual upx_byte *getLoader(int *llen=NULL);
|
||||||
|
virtual void relocate();
|
||||||
|
virtual void defineSymbol(const char *name, unsigned value);
|
||||||
|
virtual unsigned getSymbolOffset(const char *) const;
|
||||||
|
virtual void dumpSymbols(FILE *fp=NULL) const;
|
||||||
|
|
||||||
|
void alignWithByte(unsigned len, upx_byte b);
|
||||||
|
virtual void alignCode(unsigned len) { alignWithByte(len, 0); }
|
||||||
|
virtual void alignData(unsigned len) { alignWithByte(len, 0); }
|
||||||
|
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BeLinker : public Linker
|
struct ElfLinker::Section : private nocopy
|
||||||
{
|
{
|
||||||
typedef Linker super;
|
char *name;
|
||||||
public:
|
void *input;
|
||||||
BeLinker(const void *pdata, int plen, int pinfo) :
|
upx_byte *output;
|
||||||
super(pdata, plen, pinfo) { }
|
unsigned size;
|
||||||
|
unsigned offset;
|
||||||
|
unsigned char align; // log2
|
||||||
|
Section *next;
|
||||||
|
|
||||||
protected:
|
Section(const char *n, const void *i, unsigned s, unsigned a=0);
|
||||||
// big endian
|
~Section();
|
||||||
virtual unsigned get32(const void *b) const { return get_be32(b); }
|
|
||||||
virtual void set32(void *b, unsigned v) const { set_be32(b, v); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// disable copy and assignment
|
|
||||||
BeLinker(const BeLinker &); // {}
|
|
||||||
BeLinker& operator= (const BeLinker &); // { return *this; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ElfLinker::Symbol : private nocopy
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
Section *section;
|
||||||
|
unsigned offset;
|
||||||
|
|
||||||
|
Symbol(const char *n, Section *s, unsigned o);
|
||||||
|
~Symbol();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ElfLinker::Relocation : private nocopy
|
||||||
|
{
|
||||||
|
const Section *section;
|
||||||
|
unsigned offset;
|
||||||
|
const char *type;
|
||||||
|
const Symbol *value;
|
||||||
|
unsigned add; // used in .rela relocations
|
||||||
|
|
||||||
|
Relocation(const Section *s, unsigned o, const char *t,
|
||||||
|
const Symbol *v, unsigned a);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// ElfLinker arch subclasses
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
class ElfLinkerAMD64 : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); }
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerArmBE : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerArmLE : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerM68k : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void alignCode(unsigned len);
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerPpc32 : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ElfLinkerX86 : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
protected:
|
||||||
|
virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); }
|
||||||
|
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||||
|
unsigned value, const char *type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+39
-10
@@ -30,6 +30,7 @@
|
|||||||
#include "mygetopt.h"
|
#include "mygetopt.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
|
#include "p_elf.h"
|
||||||
|
|
||||||
|
|
||||||
#if 1 && defined(__DJGPP__)
|
#if 1 && defined(__DJGPP__)
|
||||||
@@ -45,7 +46,7 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
|
|||||||
void init_options(struct options_t *o)
|
void init_options(struct options_t *o)
|
||||||
{
|
{
|
||||||
memset(o, 0, sizeof(*o));
|
memset(o, 0, sizeof(*o));
|
||||||
memset(&o->crp, 0xff, sizeof(o->crp));
|
o->crp.reset();
|
||||||
|
|
||||||
o->cmd = CMD_NONE;
|
o->cmd = CMD_NONE;
|
||||||
o->method = -1;
|
o->method = -1;
|
||||||
@@ -511,6 +512,11 @@ static int do_option(int optc, const char *arg)
|
|||||||
if (!set_method(M_NRV2E_LE32, -1))
|
if (!set_method(M_NRV2E_LE32, -1))
|
||||||
e_method(M_NRV2E_LE32, opt->level);
|
e_method(M_NRV2E_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
|
case 721:
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
|
if (!set_method(M_LZMA, -1))
|
||||||
|
e_method(M_LZMA, opt->level);
|
||||||
|
break;
|
||||||
|
|
||||||
// compression level
|
// compression level
|
||||||
case '1':
|
case '1':
|
||||||
@@ -528,10 +534,11 @@ static int do_option(int optc, const char *arg)
|
|||||||
|
|
||||||
case 901: // --brute
|
case 901: // --brute
|
||||||
opt->all_methods = true;
|
opt->all_methods = true;
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
opt->all_filters = true;
|
opt->all_filters = true;
|
||||||
opt->filter = -1;
|
opt->filter = -1;
|
||||||
opt->crp.m_size = 999999;
|
opt->crp.crp_ucl.m_size = 999999;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 900: // --best
|
case 900: // --best
|
||||||
if (!set_method(-1, 10))
|
if (!set_method(-1, 10))
|
||||||
@@ -594,27 +601,27 @@ static int do_option(int optc, const char *arg)
|
|||||||
opt->all_methods = true;
|
opt->all_methods = true;
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
break;
|
break;
|
||||||
// compression parms
|
// compression runtime parameters
|
||||||
case 531:
|
case 531:
|
||||||
getoptvar(&opt->crp.c_flags, 0, 3);
|
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3);
|
||||||
break;
|
break;
|
||||||
case 532:
|
case 532:
|
||||||
getoptvar(&opt->crp.s_level, 0, 2);
|
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2);
|
||||||
break;
|
break;
|
||||||
case 533:
|
case 533:
|
||||||
getoptvar(&opt->crp.h_level, 0, 1);
|
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1);
|
||||||
break;
|
break;
|
||||||
case 534:
|
case 534:
|
||||||
getoptvar(&opt->crp.p_level, 0, 7);
|
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7);
|
||||||
break;
|
break;
|
||||||
case 535:
|
case 535:
|
||||||
getoptvar(&opt->crp.max_offset, 256u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u);
|
||||||
break;
|
break;
|
||||||
case 536:
|
case 536:
|
||||||
getoptvar(&opt->crp.max_match, 16u, ~0u);
|
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u);
|
||||||
break;
|
break;
|
||||||
case 537:
|
case 537:
|
||||||
if (getoptvar(&opt->crp.m_size, 10000u, 999999u) != 0)
|
if (getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u) != 0)
|
||||||
e_optval("--crp-ms=");
|
e_optval("--crp-ms=");
|
||||||
break;
|
break;
|
||||||
// backup
|
// backup
|
||||||
@@ -731,6 +738,18 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 665:
|
case 665:
|
||||||
opt->o_unix.make_ptinterp = true;
|
opt->o_unix.make_ptinterp = true;
|
||||||
break;
|
break;
|
||||||
|
case 666: // Linux
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||||
|
break;
|
||||||
|
case 667: // FreeBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_FREEBSD;
|
||||||
|
break;
|
||||||
|
case 668: // NetBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_NETBSD;
|
||||||
|
break;
|
||||||
|
case 669: // OpenBSD
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_OPENBSD;
|
||||||
|
break;
|
||||||
case 670:
|
case 670:
|
||||||
opt->ps1_exe.boot_only = true;
|
opt->ps1_exe.boot_only = true;
|
||||||
break;
|
break;
|
||||||
@@ -741,6 +760,9 @@ static int do_option(int optc, const char *arg)
|
|||||||
case 672:
|
case 672:
|
||||||
opt->ps1_exe.do_8bit = true;
|
opt->ps1_exe.do_8bit = true;
|
||||||
break;
|
break;
|
||||||
|
case 673:
|
||||||
|
opt->ps1_exe.do_8mb = false;
|
||||||
|
break;
|
||||||
|
|
||||||
case '\0':
|
case '\0':
|
||||||
return -1;
|
return -1;
|
||||||
@@ -824,6 +846,7 @@ static const struct mfx_option longopts[] =
|
|||||||
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
||||||
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
||||||
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
||||||
|
{"lzma", 0x10, 0, 721}, // --lzma
|
||||||
// compression settings
|
// compression settings
|
||||||
{"all-filters", 0x10, 0, 523},
|
{"all-filters", 0x10, 0, 523},
|
||||||
{"all-methods", 0x10, 0, 524},
|
{"all-methods", 0x10, 0, 524},
|
||||||
@@ -857,6 +880,10 @@ static const struct mfx_option longopts[] =
|
|||||||
{"is_ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
|
{"is_ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
|
||||||
{"use_ptinterp", 0, 0, 664}, // linux/elf386 PT_INTERP program
|
{"use_ptinterp", 0, 0, 664}, // linux/elf386 PT_INTERP program
|
||||||
{"make_ptinterp", 0, 0, 665}, // linux/elf386 PT_INTERP program
|
{"make_ptinterp", 0, 0, 665}, // linux/elf386 PT_INTERP program
|
||||||
|
{"Linux", 0, 0, 666},
|
||||||
|
{"FreeBSD", 0, 0, 667},
|
||||||
|
{"NetBSD", 0, 0, 668},
|
||||||
|
{"OpenBSD", 0, 0, 669},
|
||||||
// watcom/le
|
// watcom/le
|
||||||
{"le", 0, 0, 620}, // produce LE output
|
{"le", 0, 0, 620}, // produce LE output
|
||||||
// win32/pe
|
// win32/pe
|
||||||
@@ -870,6 +897,7 @@ static const struct mfx_option longopts[] =
|
|||||||
{"boot-only", 0x10, 0, 670},
|
{"boot-only", 0x10, 0, 670},
|
||||||
{"no-align", 0x10, 0, 671},
|
{"no-align", 0x10, 0, 671},
|
||||||
{"8-bit", 0x10, 0, 672},
|
{"8-bit", 0x10, 0, 672},
|
||||||
|
{"8mb-ram", 0x10, 0, 673},
|
||||||
|
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
@@ -880,6 +908,7 @@ static const struct mfx_option longopts[] =
|
|||||||
prepare_shortopts(buf,"123456789hH?V",longopts),
|
prepare_shortopts(buf,"123456789hH?V",longopts),
|
||||||
mfx_optind = 0;
|
mfx_optind = 0;
|
||||||
mfx_opterr = 1;
|
mfx_opterr = 1;
|
||||||
|
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||||
while ((optc = mfx_getopt_long(argc, argv, buf, longopts, &longind)) >= 0)
|
while ((optc = mfx_getopt_long(argc, argv, buf, longopts, &longind)) >= 0)
|
||||||
{
|
{
|
||||||
if (do_option(optc, argv[mfx_optind-1]) != 0)
|
if (do_option(optc, argv[mfx_optind-1]) != 0)
|
||||||
|
|||||||
+19
-6
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -101,16 +101,15 @@ void MemBuffer::dealloc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
|
unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra)
|
||||||
{
|
{
|
||||||
assert((int)uncompressed_size > 0);
|
assert((int)uncompressed_size > 0);
|
||||||
assert((int)extra >= 0);
|
assert((int)extra >= 0);
|
||||||
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
||||||
alloc(size);
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned MemBuffer::getSizeForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||||
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
|
||||||
{
|
{
|
||||||
assert((int)uncompressed_size > 0);
|
assert((int)uncompressed_size > 0);
|
||||||
assert((int)extra >= 0);
|
assert((int)extra >= 0);
|
||||||
@@ -120,6 +119,20 @@ void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra
|
|||||||
#if (ACC_ARCH_I386)
|
#if (ACC_ARCH_I386)
|
||||||
size += 3;
|
size += 3;
|
||||||
#endif
|
#endif
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra)
|
||||||
|
{
|
||||||
|
unsigned size = getSizeForCompression(uncompressed_size, extra);
|
||||||
|
alloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||||
|
{
|
||||||
|
unsigned size = getSizeForUncompression(uncompressed_size, extra);
|
||||||
alloc(size);
|
alloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,6 +41,9 @@ public:
|
|||||||
MemBuffer(unsigned size);
|
MemBuffer(unsigned size);
|
||||||
~MemBuffer();
|
~MemBuffer();
|
||||||
|
|
||||||
|
static unsigned getSizeForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
static unsigned getSizeForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
|
||||||
void alloc(unsigned size);
|
void alloc(unsigned size);
|
||||||
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||||
|
|||||||
+249
-132
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
#ifndef __ACC_H_INCLUDED
|
#ifndef __ACC_H_INCLUDED
|
||||||
#define __ACC_H_INCLUDED 1
|
#define __ACC_H_INCLUDED 1
|
||||||
#define ACC_VERSION 20060404L
|
#define ACC_VERSION 20060823L
|
||||||
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
||||||
# define __CYGWIN__ __CYGWIN32__
|
# define __CYGWIN__ __CYGWIN32__
|
||||||
#endif
|
#endif
|
||||||
@@ -301,6 +301,17 @@
|
|||||||
#if defined(_CRAY) && defined(_CRAY1)
|
#if defined(_CRAY) && defined(_CRAY1)
|
||||||
# define ACC_BROKEN_SIGNED_RIGHT_SHIFT 1
|
# define ACC_BROKEN_SIGNED_RIGHT_SHIFT 1
|
||||||
#endif
|
#endif
|
||||||
|
#define ACC_PP_STRINGIZE(x) #x
|
||||||
|
#define ACC_PP_MACRO_EXPAND(x) ACC_PP_STRINGIZE(x)
|
||||||
|
#define ACC_PP_CONCAT2(a,b) a ## b
|
||||||
|
#define ACC_PP_CONCAT3(a,b,c) a ## b ## c
|
||||||
|
#define ACC_PP_CONCAT4(a,b,c,d) a ## b ## c ## d
|
||||||
|
#define ACC_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
|
||||||
|
#define ACC_PP_ECONCAT2(a,b) ACC_PP_CONCAT2(a,b)
|
||||||
|
#define ACC_PP_ECONCAT3(a,b,c) ACC_PP_CONCAT3(a,b,c)
|
||||||
|
#define ACC_PP_ECONCAT4(a,b,c,d) ACC_PP_CONCAT4(a,b,c,d)
|
||||||
|
#define ACC_PP_ECONCAT5(a,b,c,d,e) ACC_PP_CONCAT5(a,b,c,d,e)
|
||||||
|
#if 1
|
||||||
#define ACC_CPP_STRINGIZE(x) #x
|
#define ACC_CPP_STRINGIZE(x) #x
|
||||||
#define ACC_CPP_MACRO_EXPAND(x) ACC_CPP_STRINGIZE(x)
|
#define ACC_CPP_MACRO_EXPAND(x) ACC_CPP_STRINGIZE(x)
|
||||||
#define ACC_CPP_CONCAT2(a,b) a ## b
|
#define ACC_CPP_CONCAT2(a,b) a ## b
|
||||||
@@ -311,6 +322,7 @@
|
|||||||
#define ACC_CPP_ECONCAT3(a,b,c) ACC_CPP_CONCAT3(a,b,c)
|
#define ACC_CPP_ECONCAT3(a,b,c) ACC_CPP_CONCAT3(a,b,c)
|
||||||
#define ACC_CPP_ECONCAT4(a,b,c,d) ACC_CPP_CONCAT4(a,b,c,d)
|
#define ACC_CPP_ECONCAT4(a,b,c,d) ACC_CPP_CONCAT4(a,b,c,d)
|
||||||
#define ACC_CPP_ECONCAT5(a,b,c,d,e) ACC_CPP_CONCAT5(a,b,c,d,e)
|
#define ACC_CPP_ECONCAT5(a,b,c,d,e) ACC_CPP_CONCAT5(a,b,c,d,e)
|
||||||
|
#endif
|
||||||
#define __ACC_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
|
#define __ACC_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
|
||||||
#if 1 && defined(__cplusplus)
|
#if 1 && defined(__cplusplus)
|
||||||
# if !defined(__STDC_CONSTANT_MACROS)
|
# if !defined(__STDC_CONSTANT_MACROS)
|
||||||
@@ -509,14 +521,14 @@
|
|||||||
# define ACC_CC_CILLY 1
|
# define ACC_CC_CILLY 1
|
||||||
# define ACC_INFO_CC "Cilly"
|
# define ACC_INFO_CC "Cilly"
|
||||||
# if defined(__CILLY__)
|
# if defined(__CILLY__)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__CILLY__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__CILLY__)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
# endif
|
# endif
|
||||||
#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__)
|
#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__)
|
||||||
# define ACC_CC_SDCC 1
|
# define ACC_CC_SDCC 1
|
||||||
# define ACC_INFO_CC "sdcc"
|
# define ACC_INFO_CC "sdcc"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(SDCC)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(SDCC)
|
||||||
#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
|
#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
|
||||||
# define ACC_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
|
# define ACC_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
|
||||||
# define ACC_INFO_CC "Pathscale C"
|
# define ACC_INFO_CC "Pathscale C"
|
||||||
@@ -524,7 +536,7 @@
|
|||||||
#elif defined(__INTEL_COMPILER)
|
#elif defined(__INTEL_COMPILER)
|
||||||
# define ACC_CC_INTELC 1
|
# define ACC_CC_INTELC 1
|
||||||
# define ACC_INFO_CC "Intel C"
|
# define ACC_INFO_CC "Intel C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__INTEL_COMPILER)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__INTEL_COMPILER)
|
||||||
# if defined(_WIN32) || defined(_WIN64)
|
# if defined(_WIN32) || defined(_WIN64)
|
||||||
# define ACC_CC_SYNTAX_MSC 1
|
# define ACC_CC_SYNTAX_MSC 1
|
||||||
# else
|
# else
|
||||||
@@ -533,9 +545,13 @@
|
|||||||
#elif defined(__POCC__) && defined(_WIN32)
|
#elif defined(__POCC__) && defined(_WIN32)
|
||||||
# define ACC_CC_PELLESC 1
|
# define ACC_CC_PELLESC 1
|
||||||
# define ACC_INFO_CC "Pelles C"
|
# define ACC_INFO_CC "Pelles C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__POCC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__POCC__)
|
||||||
#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
|
#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
|
||||||
# define ACC_CC_LLVM 1
|
# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
|
||||||
|
# define ACC_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
|
||||||
|
# else
|
||||||
|
# define ACC_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
|
||||||
|
# endif
|
||||||
# define ACC_INFO_CC "llvm-gcc"
|
# define ACC_INFO_CC "llvm-gcc"
|
||||||
# define ACC_INFO_CCVER __VERSION__
|
# define ACC_INFO_CCVER __VERSION__
|
||||||
#elif defined(__GNUC__) && defined(__VERSION__)
|
#elif defined(__GNUC__) && defined(__VERSION__)
|
||||||
@@ -555,23 +571,23 @@
|
|||||||
#elif defined(__AZTEC_C__)
|
#elif defined(__AZTEC_C__)
|
||||||
# define ACC_CC_AZTECC 1
|
# define ACC_CC_AZTECC 1
|
||||||
# define ACC_INFO_CC "Aztec C"
|
# define ACC_INFO_CC "Aztec C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__AZTEC_C__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__AZTEC_C__)
|
||||||
#elif defined(__BORLANDC__)
|
#elif defined(__BORLANDC__)
|
||||||
# define ACC_CC_BORLANDC 1
|
# define ACC_CC_BORLANDC 1
|
||||||
# define ACC_INFO_CC "Borland C"
|
# define ACC_INFO_CC "Borland C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__BORLANDC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__BORLANDC__)
|
||||||
#elif defined(_CRAYC) && defined(_RELEASE)
|
#elif defined(_CRAYC) && defined(_RELEASE)
|
||||||
# define ACC_CC_CRAYC 1
|
# define ACC_CC_CRAYC 1
|
||||||
# define ACC_INFO_CC "Cray C"
|
# define ACC_INFO_CC "Cray C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(_RELEASE)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(_RELEASE)
|
||||||
#elif defined(__DMC__) && defined(__SC__)
|
#elif defined(__DMC__) && defined(__SC__)
|
||||||
# define ACC_CC_DMC 1
|
# define ACC_CC_DMC 1
|
||||||
# define ACC_INFO_CC "Digital Mars C"
|
# define ACC_INFO_CC "Digital Mars C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__DMC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__DMC__)
|
||||||
#elif defined(__DECC)
|
#elif defined(__DECC)
|
||||||
# define ACC_CC_DECC 1
|
# define ACC_CC_DECC 1
|
||||||
# define ACC_INFO_CC "DEC C"
|
# define ACC_INFO_CC "DEC C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__DECC)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__DECC)
|
||||||
#elif defined(__HIGHC__)
|
#elif defined(__HIGHC__)
|
||||||
# define ACC_CC_HIGHC 1
|
# define ACC_CC_HIGHC 1
|
||||||
# define ACC_INFO_CC "MetaWare High C"
|
# define ACC_INFO_CC "MetaWare High C"
|
||||||
@@ -580,18 +596,18 @@
|
|||||||
# define ACC_CC_IARC 1
|
# define ACC_CC_IARC 1
|
||||||
# define ACC_INFO_CC "IAR C"
|
# define ACC_INFO_CC "IAR C"
|
||||||
# if defined(__VER__)
|
# if defined(__VER__)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__VER__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__VER__)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__IBMC__)
|
#elif defined(__IBMC__)
|
||||||
# define ACC_CC_IBMC 1
|
# define ACC_CC_IBMC 1
|
||||||
# define ACC_INFO_CC "IBM C"
|
# define ACC_INFO_CC "IBM C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__IBMC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__IBMC__)
|
||||||
#elif defined(__KEIL__) && defined(__C166__)
|
#elif defined(__KEIL__) && defined(__C166__)
|
||||||
# define ACC_CC_KEILC 1
|
# define ACC_CC_KEILC 1
|
||||||
# define ACC_INFO_CC "Keil C"
|
# define ACC_INFO_CC "Keil C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__C166__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__C166__)
|
||||||
#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL)
|
#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL)
|
||||||
# define ACC_CC_LCCWIN32 1
|
# define ACC_CC_LCCWIN32 1
|
||||||
# define ACC_INFO_CC "lcc-win32"
|
# define ACC_INFO_CC "lcc-win32"
|
||||||
@@ -600,7 +616,7 @@
|
|||||||
# define ACC_CC_LCC 1
|
# define ACC_CC_LCC 1
|
||||||
# define ACC_INFO_CC "lcc"
|
# define ACC_INFO_CC "lcc"
|
||||||
# if defined(__LCC_VERSION__)
|
# if defined(__LCC_VERSION__)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__LCC_VERSION__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__LCC_VERSION__)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
# endif
|
# endif
|
||||||
@@ -608,14 +624,14 @@
|
|||||||
# define ACC_CC_MSC 1
|
# define ACC_CC_MSC 1
|
||||||
# define ACC_INFO_CC "Microsoft C"
|
# define ACC_INFO_CC "Microsoft C"
|
||||||
# if defined(_MSC_FULL_VER)
|
# if defined(_MSC_FULL_VER)
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(_MSC_VER) "." ACC_CPP_MACRO_EXPAND(_MSC_FULL_VER)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(_MSC_VER) "." ACC_PP_MACRO_EXPAND(_MSC_FULL_VER)
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(_MSC_VER)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(_MSC_VER)
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__MWERKS__)
|
#elif defined(__MWERKS__)
|
||||||
# define ACC_CC_MWERKS 1
|
# define ACC_CC_MWERKS 1
|
||||||
# define ACC_INFO_CC "Metrowerks C"
|
# define ACC_INFO_CC "Metrowerks C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__MWERKS__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__MWERKS__)
|
||||||
#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
|
#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
|
||||||
# define ACC_CC_NDPC 1
|
# define ACC_CC_NDPC 1
|
||||||
# define ACC_INFO_CC "Microway NDP C"
|
# define ACC_INFO_CC "Microway NDP C"
|
||||||
@@ -623,7 +639,7 @@
|
|||||||
#elif defined(__PACIFIC__)
|
#elif defined(__PACIFIC__)
|
||||||
# define ACC_CC_PACIFICC 1
|
# define ACC_CC_PACIFICC 1
|
||||||
# define ACC_INFO_CC "Pacific C"
|
# define ACC_INFO_CC "Pacific C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__PACIFIC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__PACIFIC__)
|
||||||
#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
|
#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
|
||||||
# define ACC_CC_PGI 1
|
# define ACC_CC_PGI 1
|
||||||
# define ACC_INFO_CC "Portland Group PGI C"
|
# define ACC_INFO_CC "Portland Group PGI C"
|
||||||
@@ -631,16 +647,16 @@
|
|||||||
#elif defined(__PUREC__) && defined(__TOS__)
|
#elif defined(__PUREC__) && defined(__TOS__)
|
||||||
# define ACC_CC_PUREC 1
|
# define ACC_CC_PUREC 1
|
||||||
# define ACC_INFO_CC "Pure C"
|
# define ACC_INFO_CC "Pure C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__PUREC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__PUREC__)
|
||||||
#elif defined(__SC__) && defined(__ZTC__)
|
#elif defined(__SC__) && defined(__ZTC__)
|
||||||
# define ACC_CC_SYMANTECC 1
|
# define ACC_CC_SYMANTECC 1
|
||||||
# define ACC_INFO_CC "Symantec C"
|
# define ACC_INFO_CC "Symantec C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__SC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__SC__)
|
||||||
#elif defined(__SUNPRO_C)
|
#elif defined(__SUNPRO_C)
|
||||||
# define ACC_INFO_CC "SunPro C"
|
# define ACC_INFO_CC "SunPro C"
|
||||||
# if ((__SUNPRO_C)+0 > 0)
|
# if ((__SUNPRO_C)+0 > 0)
|
||||||
# define ACC_CC_SUNPROC __SUNPRO_C
|
# define ACC_CC_SUNPROC __SUNPRO_C
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__SUNPRO_C)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__SUNPRO_C)
|
||||||
# else
|
# else
|
||||||
# define ACC_CC_SUNPROC 1
|
# define ACC_CC_SUNPROC 1
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
@@ -649,7 +665,7 @@
|
|||||||
# define ACC_INFO_CC "SunPro C"
|
# define ACC_INFO_CC "SunPro C"
|
||||||
# if ((__SUNPRO_CC)+0 > 0)
|
# if ((__SUNPRO_CC)+0 > 0)
|
||||||
# define ACC_CC_SUNPROC __SUNPRO_CC
|
# define ACC_CC_SUNPROC __SUNPRO_CC
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__SUNPRO_CC)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__SUNPRO_CC)
|
||||||
# else
|
# else
|
||||||
# define ACC_CC_SUNPROC 1
|
# define ACC_CC_SUNPROC 1
|
||||||
# define ACC_INFO_CCVER "unknown"
|
# define ACC_INFO_CCVER "unknown"
|
||||||
@@ -657,26 +673,26 @@
|
|||||||
#elif defined(__TINYC__)
|
#elif defined(__TINYC__)
|
||||||
# define ACC_CC_TINYC 1
|
# define ACC_CC_TINYC 1
|
||||||
# define ACC_INFO_CC "Tiny C"
|
# define ACC_INFO_CC "Tiny C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__TINYC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__TINYC__)
|
||||||
#elif defined(__TSC__)
|
#elif defined(__TSC__)
|
||||||
# define ACC_CC_TOPSPEEDC 1
|
# define ACC_CC_TOPSPEEDC 1
|
||||||
# define ACC_INFO_CC "TopSpeed C"
|
# define ACC_INFO_CC "TopSpeed C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__TSC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__TSC__)
|
||||||
#elif defined(__WATCOMC__)
|
#elif defined(__WATCOMC__)
|
||||||
# define ACC_CC_WATCOMC 1
|
# define ACC_CC_WATCOMC 1
|
||||||
# define ACC_INFO_CC "Watcom C"
|
# define ACC_INFO_CC "Watcom C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__WATCOMC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__WATCOMC__)
|
||||||
#elif defined(__TURBOC__)
|
#elif defined(__TURBOC__)
|
||||||
# define ACC_CC_TURBOC 1
|
# define ACC_CC_TURBOC 1
|
||||||
# define ACC_INFO_CC "Turbo C"
|
# define ACC_INFO_CC "Turbo C"
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__TURBOC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__TURBOC__)
|
||||||
#elif defined(__ZTC__)
|
#elif defined(__ZTC__)
|
||||||
# define ACC_CC_ZORTECHC 1
|
# define ACC_CC_ZORTECHC 1
|
||||||
# define ACC_INFO_CC "Zortech C"
|
# define ACC_INFO_CC "Zortech C"
|
||||||
# if (__ZTC__ == 0x310)
|
# if (__ZTC__ == 0x310)
|
||||||
# define ACC_INFO_CCVER "0x310"
|
# define ACC_INFO_CCVER "0x310"
|
||||||
# else
|
# else
|
||||||
# define ACC_INFO_CCVER ACC_CPP_MACRO_EXPAND(__ZTC__)
|
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__ZTC__)
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define ACC_CC_UNKNOWN 1
|
# define ACC_CC_UNKNOWN 1
|
||||||
@@ -1299,6 +1315,10 @@ extern "C" {
|
|||||||
# define ACC_ABI_BIG_ENDIAN 1
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
|
#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
|
||||||
# define ACC_ABI_LITTLE_ENDIAN 1
|
# define ACC_ABI_LITTLE_ENDIAN 1
|
||||||
|
#elif 1 && (ACC_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__)
|
||||||
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
|
#elif 1 && (ACC_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__)
|
||||||
|
# define ACC_ABI_LITTLE_ENDIAN 1
|
||||||
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
|
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
|
||||||
# define ACC_ABI_BIG_ENDIAN 1
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
|
#elif 1 && (ACC_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
|
||||||
@@ -1382,6 +1402,9 @@ extern "C" {
|
|||||||
#else
|
#else
|
||||||
# define __acc_gnuc_extension__
|
# define __acc_gnuc_extension__
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(__acc_ua_volatile)
|
||||||
|
# define __acc_ua_volatile volatile
|
||||||
|
#endif
|
||||||
#if !defined(__acc_alignof)
|
#if !defined(__acc_alignof)
|
||||||
#if (ACC_CC_CILLY || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE || ACC_CC_PGI)
|
#if (ACC_CC_CILLY || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE || ACC_CC_PGI)
|
||||||
# define __acc_alignof(e) __alignof__(e)
|
# define __acc_alignof(e) __alignof__(e)
|
||||||
@@ -1391,6 +1414,36 @@ extern "C" {
|
|||||||
# define __acc_alignof(e) __alignof(e)
|
# define __acc_alignof(e) __alignof(e)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_alignof)
|
||||||
|
# define __acc_HAVE_alignof 1
|
||||||
|
#endif
|
||||||
|
#if !defined(__acc_constructor)
|
||||||
|
#if (ACC_CC_GNUC >= 0x030400ul)
|
||||||
|
# define __acc_constructor __attribute__((__constructor__,__used__))
|
||||||
|
#elif (ACC_CC_GNUC >= 0x020700ul)
|
||||||
|
# define __acc_constructor __attribute__((__constructor__))
|
||||||
|
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||||
|
# define __acc_constructor __attribute__((__constructor__))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(__acc_constructor)
|
||||||
|
# define __acc_HAVE_constructor 1
|
||||||
|
#endif
|
||||||
|
#if !defined(__acc_destructor)
|
||||||
|
#if (ACC_CC_GNUC >= 0x030400ul)
|
||||||
|
# define __acc_destructor __attribute__((__destructor__,__used__))
|
||||||
|
#elif (ACC_CC_GNUC >= 0x020700ul)
|
||||||
|
# define __acc_destructor __attribute__((__destructor__))
|
||||||
|
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||||
|
# define __acc_destructor __attribute__((__destructor__))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(__acc_destructor)
|
||||||
|
# define __acc_HAVE_destructor 1
|
||||||
|
#endif
|
||||||
|
#if defined(__acc_HAVE_destructor) && !defined(__acc_HAVE_constructor)
|
||||||
|
# error "this should not happen"
|
||||||
|
#endif
|
||||||
#if !defined(__acc_inline)
|
#if !defined(__acc_inline)
|
||||||
#if (ACC_CC_TURBOC && (__TURBOC__ <= 0x0295))
|
#if (ACC_CC_TURBOC && (__TURBOC__ <= 0x0295))
|
||||||
#elif defined(__cplusplus)
|
#elif defined(__cplusplus)
|
||||||
@@ -1411,6 +1464,11 @@ extern "C" {
|
|||||||
# define __acc_inline inline
|
# define __acc_inline inline
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_inline)
|
||||||
|
# define __acc_HAVE_inline 1
|
||||||
|
#else
|
||||||
|
# define __acc_inline
|
||||||
|
#endif
|
||||||
#if !defined(__acc_forceinline)
|
#if !defined(__acc_forceinline)
|
||||||
#if (ACC_CC_GNUC >= 0x030200ul)
|
#if (ACC_CC_GNUC >= 0x030200ul)
|
||||||
# define __acc_forceinline __inline__ __attribute__((__always_inline__))
|
# define __acc_forceinline __inline__ __attribute__((__always_inline__))
|
||||||
@@ -1424,6 +1482,11 @@ extern "C" {
|
|||||||
# define __acc_forceinline __forceinline
|
# define __acc_forceinline __forceinline
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_forceinline)
|
||||||
|
# define __acc_HAVE_forceinline 1
|
||||||
|
#else
|
||||||
|
# define __acc_forceinline
|
||||||
|
#endif
|
||||||
#if !defined(__acc_noinline)
|
#if !defined(__acc_noinline)
|
||||||
#if 1 && (ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x040000ul) && (ACC_CC_GNUC < 0x040003ul)
|
#if 1 && (ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x040000ul) && (ACC_CC_GNUC < 0x040003ul)
|
||||||
# define __acc_noinline __attribute__((__noinline__,__used__))
|
# define __acc_noinline __attribute__((__noinline__,__used__))
|
||||||
@@ -1444,7 +1507,12 @@ extern "C" {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if (defined(__acc_forceinline) || defined(__acc_noinline)) && !defined(__acc_inline)
|
#if defined(__acc_noinline)
|
||||||
|
# define __acc_HAVE_noinline 1
|
||||||
|
#else
|
||||||
|
# define __acc_noinline
|
||||||
|
#endif
|
||||||
|
#if (defined(__acc_HAVE_forceinline) || defined(__acc_HAVE_noinline)) && !defined(__acc_HAVE_inline)
|
||||||
# error "this should not happen"
|
# error "this should not happen"
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_noreturn)
|
#if !defined(__acc_noreturn)
|
||||||
@@ -1460,6 +1528,11 @@ extern "C" {
|
|||||||
# define __acc_noreturn __declspec(noreturn)
|
# define __acc_noreturn __declspec(noreturn)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__acc_noreturn)
|
||||||
|
# define __acc_HAVE_noreturn 1
|
||||||
|
#else
|
||||||
|
# define __acc_noreturn
|
||||||
|
#endif
|
||||||
#if !defined(__acc_nothrow)
|
#if !defined(__acc_nothrow)
|
||||||
#if (ACC_CC_GNUC >= 0x030300ul)
|
#if (ACC_CC_GNUC >= 0x030300ul)
|
||||||
# define __acc_nothrow __attribute__((__nothrow__))
|
# define __acc_nothrow __attribute__((__nothrow__))
|
||||||
@@ -1473,26 +1546,10 @@ extern "C" {
|
|||||||
# define __acc_nothrow __declspec(nothrow)
|
# define __acc_nothrow __declspec(nothrow)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_constructor)
|
#if defined(__acc_nothrow)
|
||||||
#if (ACC_CC_GNUC >= 0x030400ul)
|
# define __acc_HAVE_nothrow 1
|
||||||
# define __acc_constructor __attribute__((__constructor__,__used__))
|
#else
|
||||||
#elif (ACC_CC_GNUC >= 0x020700ul)
|
# define __acc_nothrow
|
||||||
# define __acc_constructor __attribute__((__constructor__))
|
|
||||||
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
|
||||||
# define __acc_constructor __attribute__((__constructor__))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if !defined(__acc_destructor)
|
|
||||||
#if (ACC_CC_GNUC >= 0x030400ul)
|
|
||||||
# define __acc_destructor __attribute__((__destructor__,__used__))
|
|
||||||
#elif (ACC_CC_GNUC >= 0x020700ul)
|
|
||||||
# define __acc_destructor __attribute__((__destructor__))
|
|
||||||
#elif (ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
|
||||||
# define __acc_destructor __attribute__((__destructor__))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if defined(__acc_destructor) && !defined(__acc_constructor)
|
|
||||||
# error "this should not happen"
|
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_restrict)
|
#if !defined(__acc_restrict)
|
||||||
#if (ACC_CC_GNUC >= 0x030400ul)
|
#if (ACC_CC_GNUC >= 0x030400ul)
|
||||||
@@ -1505,8 +1562,10 @@ extern "C" {
|
|||||||
# define __acc_restrict __restrict
|
# define __acc_restrict __restrict
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_ua_volatile)
|
#if defined(__acc_restrict)
|
||||||
# define __acc_ua_volatile volatile
|
# define __acc_HAVE_restrict 1
|
||||||
|
#else
|
||||||
|
# define __acc_restrict
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_likely) && !defined(__acc_unlikely)
|
#if !defined(__acc_likely) && !defined(__acc_unlikely)
|
||||||
#if (ACC_CC_GNUC >= 0x030200ul)
|
#if (ACC_CC_GNUC >= 0x030200ul)
|
||||||
@@ -1520,10 +1579,14 @@ extern "C" {
|
|||||||
# define __acc_unlikely(e) (__builtin_expect(!!(e),0))
|
# define __acc_unlikely(e) (__builtin_expect(!!(e),0))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_likely)
|
#if defined(__acc_likely)
|
||||||
|
# define __acc_HAVE_likely 1
|
||||||
|
#else
|
||||||
# define __acc_likely(e) (e)
|
# define __acc_likely(e) (e)
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_unlikely)
|
#if defined(__acc_unlikely)
|
||||||
|
# define __acc_HAVE_unlikely 1
|
||||||
|
#else
|
||||||
# define __acc_unlikely(e) (e)
|
# define __acc_unlikely(e) (e)
|
||||||
#endif
|
#endif
|
||||||
#if !defined(ACC_UNUSED)
|
#if !defined(ACC_UNUSED)
|
||||||
@@ -2453,6 +2516,45 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define ACC_SIZEOF_ACC_INT32E_T 4
|
# define ACC_SIZEOF_ACC_INT32E_T 4
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(acc_int64e_t)
|
||||||
|
#if (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define ACC_CFG_TYPE_PREFER___INT64 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if (ACC_SIZEOF_INT == 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
||||||
|
# define acc_int64e_t int
|
||||||
|
# define acc_uint64e_t unsigned int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_INT
|
||||||
|
#elif (ACC_SIZEOF_LONG == 8)
|
||||||
|
# define acc_int64e_t long int
|
||||||
|
# define acc_uint64e_t unsigned long int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG
|
||||||
|
#elif (ACC_SIZEOF_LONG_LONG == 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define acc_int64e_t acc_llong_t
|
||||||
|
# define acc_uint64e_t acc_ullong_t
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0ll)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ull)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##LL
|
||||||
|
# define ACC_UINT64_C(c) c##ULL
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG_LONG
|
||||||
|
#elif (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# define acc_int64e_t __int64
|
||||||
|
# define acc_uint64e_t unsigned __int64
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0i64)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##i64
|
||||||
|
# define ACC_UINT64_C(c) c##ui64
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF___INT64
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if !defined(acc_int32l_t)
|
#if !defined(acc_int32l_t)
|
||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define acc_int32l_t acc_int32e_t
|
# define acc_int32l_t acc_int32e_t
|
||||||
@@ -2471,41 +2573,10 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(acc_int64l_t)
|
#if !defined(acc_int64l_t)
|
||||||
#if (ACC_SIZEOF___INT64 >= 8)
|
#if defined(acc_int64e_t)
|
||||||
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
# define acc_int64l_t acc_int64e_t
|
||||||
# define ACC_CFG_TYPE_PREFER___INT64 1
|
# define acc_uint64l_t acc_uint64e_t
|
||||||
# endif
|
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
#endif
|
|
||||||
#if (ACC_SIZEOF_INT >= 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
|
||||||
# define acc_int64l_t int
|
|
||||||
# define acc_uint64l_t unsigned int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_INT
|
|
||||||
#elif (ACC_SIZEOF_LONG >= 8)
|
|
||||||
# define acc_int64l_t long int
|
|
||||||
# define acc_uint64l_t unsigned long int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG
|
|
||||||
#elif (ACC_SIZEOF_LONG_LONG >= 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
|
||||||
# define acc_int64l_t acc_llong_t
|
|
||||||
# define acc_uint64l_t acc_ullong_t
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0ll)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ull)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##LL
|
|
||||||
# define ACC_UINT64_C(c) c##ULL
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG_LONG
|
|
||||||
#elif (ACC_SIZEOF___INT64 >= 8)
|
|
||||||
# define acc_int64l_t __int64
|
|
||||||
# define acc_uint64l_t unsigned __int64
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0i64)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##i64
|
|
||||||
# define ACC_UINT64_C(c) c##ui64
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF___INT64
|
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -2650,6 +2721,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
||||||
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(SIZEOF_ACC_INT64E_T) && defined(ACC_SIZEOF_ACC_INT64E_T)
|
||||||
|
# define SIZEOF_ACC_INT64E_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
|
#endif
|
||||||
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
||||||
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
||||||
#endif
|
#endif
|
||||||
@@ -2861,6 +2935,45 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define ACC_SIZEOF_ACC_INT32E_T 4
|
# define ACC_SIZEOF_ACC_INT32E_T 4
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(acc_int64e_t)
|
||||||
|
#if (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define ACC_CFG_TYPE_PREFER___INT64 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if (ACC_SIZEOF_INT == 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
||||||
|
# define acc_int64e_t int
|
||||||
|
# define acc_uint64e_t unsigned int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_INT
|
||||||
|
#elif (ACC_SIZEOF_LONG == 8)
|
||||||
|
# define acc_int64e_t long int
|
||||||
|
# define acc_uint64e_t unsigned long int
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG
|
||||||
|
#elif (ACC_SIZEOF_LONG_LONG == 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
||||||
|
# define acc_int64e_t acc_llong_t
|
||||||
|
# define acc_uint64e_t acc_ullong_t
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0ll)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ull)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##LL
|
||||||
|
# define ACC_UINT64_C(c) c##ULL
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF_LONG_LONG
|
||||||
|
#elif (ACC_SIZEOF___INT64 == 8)
|
||||||
|
# define acc_int64e_t __int64
|
||||||
|
# define acc_uint64e_t unsigned __int64
|
||||||
|
# if (ACC_CC_BORLANDC)
|
||||||
|
# define ACC_INT64_C(c) ((c) + 0i64)
|
||||||
|
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
||||||
|
# else
|
||||||
|
# define ACC_INT64_C(c) c##i64
|
||||||
|
# define ACC_UINT64_C(c) c##ui64
|
||||||
|
# endif
|
||||||
|
# define ACC_SIZEOF_ACC_INT64E_T ACC_SIZEOF___INT64
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if !defined(acc_int32l_t)
|
#if !defined(acc_int32l_t)
|
||||||
#if defined(acc_int32e_t)
|
#if defined(acc_int32e_t)
|
||||||
# define acc_int32l_t acc_int32e_t
|
# define acc_int32l_t acc_int32e_t
|
||||||
@@ -2879,41 +2992,10 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(acc_int64l_t)
|
#if !defined(acc_int64l_t)
|
||||||
#if (ACC_SIZEOF___INT64 >= 8)
|
#if defined(acc_int64e_t)
|
||||||
# if (ACC_CC_BORLANDC) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
# define acc_int64l_t acc_int64e_t
|
||||||
# define ACC_CFG_TYPE_PREFER___INT64 1
|
# define acc_uint64l_t acc_uint64e_t
|
||||||
# endif
|
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
#endif
|
|
||||||
#if (ACC_SIZEOF_INT >= 8) && (ACC_SIZEOF_INT < ACC_SIZEOF_LONG)
|
|
||||||
# define acc_int64l_t int
|
|
||||||
# define acc_uint64l_t unsigned int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_INT
|
|
||||||
#elif (ACC_SIZEOF_LONG >= 8)
|
|
||||||
# define acc_int64l_t long int
|
|
||||||
# define acc_uint64l_t unsigned long int
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG
|
|
||||||
#elif (ACC_SIZEOF_LONG_LONG >= 8) && !defined(ACC_CFG_TYPE_PREFER___INT64)
|
|
||||||
# define acc_int64l_t acc_llong_t
|
|
||||||
# define acc_uint64l_t acc_ullong_t
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0ll)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ull)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##LL
|
|
||||||
# define ACC_UINT64_C(c) c##ULL
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF_LONG_LONG
|
|
||||||
#elif (ACC_SIZEOF___INT64 >= 8)
|
|
||||||
# define acc_int64l_t __int64
|
|
||||||
# define acc_uint64l_t unsigned __int64
|
|
||||||
# if (ACC_CC_BORLANDC)
|
|
||||||
# define ACC_INT64_C(c) ((c) + 0i64)
|
|
||||||
# define ACC_UINT64_C(c) ((c) + 0ui64)
|
|
||||||
# else
|
|
||||||
# define ACC_INT64_C(c) c##i64
|
|
||||||
# define ACC_UINT64_C(c) c##ui64
|
|
||||||
# endif
|
|
||||||
# define ACC_SIZEOF_ACC_INT64L_T ACC_SIZEOF___INT64
|
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -3058,6 +3140,9 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
|
|||||||
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
#if !defined(SIZEOF_ACC_INT32E_T) && defined(ACC_SIZEOF_ACC_INT32E_T)
|
||||||
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
# define SIZEOF_ACC_INT32E_T ACC_SIZEOF_ACC_INT32E_T
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(SIZEOF_ACC_INT64E_T) && defined(ACC_SIZEOF_ACC_INT64E_T)
|
||||||
|
# define SIZEOF_ACC_INT64E_T ACC_SIZEOF_ACC_INT64E_T
|
||||||
|
#endif
|
||||||
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
#if !defined(SIZEOF_ACC_INT32L_T) && defined(ACC_SIZEOF_ACC_INT32L_T)
|
||||||
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
# define SIZEOF_ACC_INT32L_T ACC_SIZEOF_ACC_INT32L_T
|
||||||
#endif
|
#endif
|
||||||
@@ -3234,7 +3319,9 @@ typedef unsigned short wchar_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus) && defined(__GNUC__) && (__GNUC__ >= 4)
|
||||||
|
#define NULL __null
|
||||||
|
#elif defined(__cplusplus)
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
#else
|
#else
|
||||||
#define NULL ((void*)0)
|
#define NULL ((void*)0)
|
||||||
@@ -3731,8 +3818,10 @@ ACCLIB_EXTERN(int, acc_mkdir) (const char*, unsigned);
|
|||||||
ACCLIB_EXTERN(int, acc_rmdir) (const char*);
|
ACCLIB_EXTERN(int, acc_rmdir) (const char*);
|
||||||
ACCLIB_EXTERN(int, acc_response) (int*, char***);
|
ACCLIB_EXTERN(int, acc_response) (int*, char***);
|
||||||
ACCLIB_EXTERN(int, acc_set_binmode) (int, int);
|
ACCLIB_EXTERN(int, acc_set_binmode) (int, int);
|
||||||
ACCLIB_EXTERN(acc_int32l_t, acc_muldiv32) (acc_int32l_t, acc_int32l_t, acc_int32l_t);
|
#if defined(acc_int32e_t)
|
||||||
ACCLIB_EXTERN(acc_uint32l_t, acc_umuldiv32) (acc_uint32l_t, acc_uint32l_t, acc_uint32l_t);
|
ACCLIB_EXTERN(acc_int32e_t, acc_muldiv32s) (acc_int32e_t, acc_int32e_t, acc_int32e_t);
|
||||||
|
ACCLIB_EXTERN(acc_uint32e_t, acc_muldiv32u) (acc_uint32e_t, acc_uint32e_t, acc_uint32e_t);
|
||||||
|
#endif
|
||||||
ACCLIB_EXTERN(void, acc_wildargv) (int*, char***);
|
ACCLIB_EXTERN(void, acc_wildargv) (int*, char***);
|
||||||
ACCLIB_EXTERN_NOINLINE(void, acc_debug_break) (void);
|
ACCLIB_EXTERN_NOINLINE(void, acc_debug_break) (void);
|
||||||
ACCLIB_EXTERN_NOINLINE(void, acc_debug_nop) (void);
|
ACCLIB_EXTERN_NOINLINE(void, acc_debug_nop) (void);
|
||||||
@@ -4332,7 +4421,21 @@ ACCLIB_EXTERN(int, acc_spawnve) (int mode, const char* fn, const char* const * a
|
|||||||
ACCCHK_ASSERT(((( (acc_int32f_t)1 << 30) + 1) >> 30) == 1)
|
ACCCHK_ASSERT(((( (acc_int32f_t)1 << 30) + 1) >> 30) == 1)
|
||||||
ACCCHK_ASSERT_IS_UNSIGNED_T(acc_uint32f_t)
|
ACCCHK_ASSERT_IS_UNSIGNED_T(acc_uint32f_t)
|
||||||
ACCCHK_ASSERT(((( (acc_uint32f_t)1 << 31) + 1) >> 31) == 1)
|
ACCCHK_ASSERT(((( (acc_uint32f_t)1 << 31) + 1) >> 31) == 1)
|
||||||
|
#if defined(acc_int64e_t)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64e_t) == 8)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64e_t) == SIZEOF_ACC_INT64E_T)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_uint64e_t) == 8)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64e_t) == sizeof(acc_uint64e_t))
|
||||||
|
ACCCHK_ASSERT_IS_SIGNED_T(acc_int64e_t)
|
||||||
|
#if (ACC_CC_BORLANDC && (__BORLANDC__ < 0x0530))
|
||||||
|
#else
|
||||||
|
ACCCHK_ASSERT_IS_UNSIGNED_T(acc_uint64e_t)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if defined(acc_int64l_t)
|
#if defined(acc_int64l_t)
|
||||||
|
#if defined(acc_int64e_t)
|
||||||
|
ACCCHK_ASSERT(sizeof(acc_int64l_t) >= sizeof(acc_int64e_t))
|
||||||
|
#endif
|
||||||
ACCCHK_ASSERT(sizeof(acc_int64l_t) >= 8)
|
ACCCHK_ASSERT(sizeof(acc_int64l_t) >= 8)
|
||||||
ACCCHK_ASSERT(sizeof(acc_int64l_t) == SIZEOF_ACC_INT64L_T)
|
ACCCHK_ASSERT(sizeof(acc_int64l_t) == SIZEOF_ACC_INT64L_T)
|
||||||
ACCCHK_ASSERT(sizeof(acc_uint64l_t) >= 8)
|
ACCCHK_ASSERT(sizeof(acc_uint64l_t) >= 8)
|
||||||
@@ -6191,20 +6294,34 @@ ACCLIB_PUBLIC(int, acc_rmdir) (const char* name)
|
|||||||
return rmdir(name);
|
return rmdir(name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ACCLIB_PUBLIC(acc_int32l_t, acc_muldiv32) (acc_int32l_t a, acc_int32l_t b, acc_int32l_t x)
|
#if defined(acc_int32e_t)
|
||||||
|
ACCLIB_PUBLIC(acc_int32e_t, acc_muldiv32s) (acc_int32e_t a, acc_int32e_t b, acc_int32e_t x)
|
||||||
{
|
{
|
||||||
acc_int32l_t r = 0;
|
acc_int32e_t r = 0;
|
||||||
if (x == 0) return x;
|
if __acc_likely(x != 0)
|
||||||
|
{
|
||||||
|
#if defined(acc_int64l_t)
|
||||||
|
r = (acc_int32e_t) (((acc_int64l_t) a * b) / x);
|
||||||
|
#else
|
||||||
ACC_UNUSED(a); ACC_UNUSED(b);
|
ACC_UNUSED(a); ACC_UNUSED(b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
ACCLIB_PUBLIC(acc_uint32l_t, acc_umuldiv32) (acc_uint32l_t a, acc_uint32l_t b, acc_uint32l_t x)
|
ACCLIB_PUBLIC(acc_uint32e_t, acc_muldiv32u) (acc_uint32e_t a, acc_uint32e_t b, acc_uint32e_t x)
|
||||||
{
|
{
|
||||||
acc_uint32l_t r = 0;
|
acc_uint32e_t r = 0;
|
||||||
if (x == 0) return x;
|
if __acc_likely(x != 0)
|
||||||
|
{
|
||||||
|
#if defined(acc_int64l_t)
|
||||||
|
r = (acc_uint32e_t) (((acc_uint64l_t) a * b) / x);
|
||||||
|
#else
|
||||||
ACC_UNUSED(a); ACC_UNUSED(b);
|
ACC_UNUSED(a); ACC_UNUSED(b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#if (ACC_OS_WIN32 && ACC_CC_PELLESC && (__POCC__ >= 290))
|
#if (ACC_OS_WIN32 && ACC_CC_PELLESC && (__POCC__ >= 290))
|
||||||
# pragma warn(push)
|
# pragma warn(push)
|
||||||
# pragma warn(disable:2007)
|
# pragma warn(disable:2007)
|
||||||
|
|||||||
+2
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
-7
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -50,6 +50,7 @@ struct options_t {
|
|||||||
int level; // compression level 1..10
|
int level; // compression level 1..10
|
||||||
int filter; // preferred filter from Packer::getFilters()
|
int filter; // preferred filter from Packer::getFilters()
|
||||||
bool all_methods; // try all available compression methods ?
|
bool all_methods; // try all available compression methods ?
|
||||||
|
bool all_methods_use_lzma;
|
||||||
bool all_filters; // try all available filters ?
|
bool all_filters; // try all available filters ?
|
||||||
bool no_filter; // force no filter
|
bool no_filter; // force no filter
|
||||||
|
|
||||||
@@ -83,15 +84,33 @@ struct options_t {
|
|||||||
int overlay;
|
int overlay;
|
||||||
|
|
||||||
// compression runtime parameters - see struct ucl_compress_config_t
|
// compression runtime parameters - see struct ucl_compress_config_t
|
||||||
struct {
|
struct crp_lzma_t {
|
||||||
upx_uint max_offset;
|
int dummy;
|
||||||
upx_uint max_match;
|
#if 0
|
||||||
|
unsigned pos_bits; // pb
|
||||||
|
unsigned lit_pos_bits; // lp
|
||||||
|
unsigned lit_context_bits; // lc
|
||||||
|
unsigned dict_size;
|
||||||
|
unsigned mf_passes;
|
||||||
|
#endif
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
struct crp_ucl_t {
|
||||||
|
unsigned max_offset;
|
||||||
|
unsigned max_match;
|
||||||
int s_level;
|
int s_level;
|
||||||
int h_level;
|
int h_level;
|
||||||
int p_level;
|
int p_level;
|
||||||
int c_flags;
|
int c_flags;
|
||||||
upx_uint m_size;
|
unsigned m_size;
|
||||||
} crp;
|
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
struct crp_t {
|
||||||
|
crp_lzma_t crp_lzma;
|
||||||
|
crp_ucl_t crp_ucl;
|
||||||
|
void reset() { crp_lzma.reset(); crp_ucl.reset(); }
|
||||||
|
};
|
||||||
|
crp_t crp;
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
enum {
|
enum {
|
||||||
@@ -120,6 +139,7 @@ struct options_t {
|
|||||||
bool boot_only;
|
bool boot_only;
|
||||||
bool no_align;
|
bool no_align;
|
||||||
bool do_8bit;
|
bool do_8bit;
|
||||||
|
bool do_8mb;
|
||||||
} ps1_exe;
|
} ps1_exe;
|
||||||
struct {
|
struct {
|
||||||
unsigned blocksize;
|
unsigned blocksize;
|
||||||
@@ -127,6 +147,7 @@ struct options_t {
|
|||||||
bool is_ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
bool is_ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
||||||
bool use_ptinterp; // use PT_INTERP /opt/upx/run
|
bool use_ptinterp; // use PT_INTERP /opt/upx/run
|
||||||
bool make_ptinterp; // make PT_INTERP [ignore current file!]
|
bool make_ptinterp; // make PT_INTERP [ignore current file!]
|
||||||
|
unsigned char osabi0; // replacement if 0==.e_ident[EI_OSABI]
|
||||||
enum { SCRIPT_MAX = 32 };
|
enum { SCRIPT_MAX = 32 };
|
||||||
const char *script_name;
|
const char *script_name;
|
||||||
} o_unix;
|
} o_unix;
|
||||||
|
|||||||
+69
-1466
File diff suppressed because it is too large
Load Diff
+9
-194
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,223 +29,38 @@
|
|||||||
#ifndef __UPX_P_ARMPE_H
|
#ifndef __UPX_P_ARMPE_H
|
||||||
#define __UPX_P_ARMPE_H
|
#define __UPX_P_ARMPE_H
|
||||||
|
|
||||||
|
|
||||||
class PackArmPe_Interval;
|
|
||||||
class PackArmPe_Reloc;
|
|
||||||
class PackArmPe_Resource;
|
|
||||||
class PackArmPe_Export;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// arm/pe
|
// arm/pe
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackArmPe : public Packer
|
class PackArmPe : public PeFile
|
||||||
{
|
{
|
||||||
typedef Packer super;
|
typedef PeFile super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackArmPe(InputFile *f);
|
PackArmPe(InputFile *f);
|
||||||
~PackArmPe();
|
~PackArmPe();
|
||||||
virtual int getVersion() const { return 13; }
|
|
||||||
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
||||||
virtual const char *getName() const { return "arm/pe"; }
|
virtual const char *getName() const { return "arm/pe"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
virtual void pack(OutputFile *fo);
|
virtual void pack(OutputFile *fo);
|
||||||
virtual void unpack(OutputFile *fo);
|
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
// unpacker capabilities
|
|
||||||
virtual bool canUnpackVersion(int version) const
|
|
||||||
{ return version == 13; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int readFileHeader();
|
|
||||||
virtual bool testUnpackVersion(int version) const;
|
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
unsigned pe_offset;
|
virtual unsigned processImports();
|
||||||
|
virtual void processImports(unsigned, unsigned);
|
||||||
|
virtual void rebuildImports(upx_byte *&);
|
||||||
|
|
||||||
unsigned processImports();
|
virtual void processTls(Interval *);
|
||||||
void processImports(unsigned, unsigned);
|
|
||||||
void rebuildImports(upx_byte *&);
|
|
||||||
upx_byte *oimport;
|
|
||||||
unsigned soimport;
|
|
||||||
upx_byte *oimpdlls;
|
|
||||||
unsigned soimpdlls;
|
|
||||||
|
|
||||||
void processRelocs();
|
|
||||||
void processRelocs(PackArmPe_Reloc *);
|
|
||||||
void rebuildRelocs(upx_byte *&);
|
|
||||||
upx_byte *orelocs;
|
|
||||||
unsigned sorelocs;
|
|
||||||
upx_byte *oxrelocs;
|
|
||||||
unsigned soxrelocs;
|
|
||||||
|
|
||||||
void processExports(PackArmPe_Export *);
|
|
||||||
void processExports(PackArmPe_Export *,unsigned);
|
|
||||||
void rebuildExports();
|
|
||||||
upx_byte *oexport;
|
|
||||||
unsigned soexport;
|
|
||||||
|
|
||||||
void processResources(PackArmPe_Resource *);
|
|
||||||
void processResources(PackArmPe_Resource *, unsigned);
|
|
||||||
void rebuildResources(upx_byte *&);
|
|
||||||
upx_byte *oresources;
|
|
||||||
unsigned soresources;
|
|
||||||
|
|
||||||
void processTls(PackArmPe_Interval *);
|
|
||||||
void processTls(PackArmPe_Reloc *,const PackArmPe_Interval *,unsigned);
|
|
||||||
void rebuildTls();
|
|
||||||
upx_byte *otls;
|
|
||||||
unsigned sotls;
|
|
||||||
|
|
||||||
unsigned stripDebug(unsigned);
|
|
||||||
|
|
||||||
unsigned icondir_offset;
|
|
||||||
int icondir_count;
|
|
||||||
|
|
||||||
bool importbyordinal;
|
|
||||||
bool kernel32ordinal;
|
|
||||||
unsigned tlsindex;
|
|
||||||
unsigned rvamin;
|
|
||||||
unsigned cimports; // rva of preprocessed imports
|
|
||||||
unsigned crelocs; // rva of preprocessed fixups
|
|
||||||
int big_relocs;
|
|
||||||
|
|
||||||
bool use_thumb_stub;
|
bool use_thumb_stub;
|
||||||
|
|
||||||
void createLinker(const void *pdata, int plen, int pinfo);
|
|
||||||
int rpatch_le32(void *b, int blen, const void *old, unsigned new_,
|
|
||||||
PackArmPe_Reloc &, unsigned);
|
|
||||||
|
|
||||||
struct pe_header_t
|
|
||||||
{
|
|
||||||
// 0x0
|
|
||||||
char _[4]; // pemagic
|
|
||||||
LE16 cpu;
|
|
||||||
LE16 objects;
|
|
||||||
char __[12]; // timestamp + reserved
|
|
||||||
LE16 opthdrsize;
|
|
||||||
LE16 flags;
|
|
||||||
// optional header
|
|
||||||
char ___[4]; // coffmagic + linkerversion
|
|
||||||
LE32 codesize;
|
|
||||||
// 0x20
|
|
||||||
LE32 datasize;
|
|
||||||
LE32 bsssize;
|
|
||||||
LE32 entry;
|
|
||||||
LE32 codebase;
|
|
||||||
// 0x30
|
|
||||||
LE32 database;
|
|
||||||
// nt specific fields
|
|
||||||
LE32 imagebase;
|
|
||||||
LE32 objectalign;
|
|
||||||
LE32 filealign; // should set to 0x200 ?
|
|
||||||
// 0x40
|
|
||||||
char ____[16]; // versions
|
|
||||||
// 0x50
|
|
||||||
LE32 imagesize;
|
|
||||||
LE32 headersize;
|
|
||||||
LE32 chksum; // should set to 0
|
|
||||||
LE16 subsystem;
|
|
||||||
LE16 dllflags;
|
|
||||||
// 0x60
|
|
||||||
char _____[20]; // stack + heap sizes
|
|
||||||
// 0x74
|
|
||||||
LE32 ddirsentries; // usually 16
|
|
||||||
|
|
||||||
struct ddirs_t
|
|
||||||
{
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct ddirs_t ddirs[16];
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct pe_section_t
|
|
||||||
{
|
|
||||||
char name[8];
|
|
||||||
LE32 vsize;
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
LE32 rawdataptr;
|
|
||||||
char _[12];
|
|
||||||
LE32 flags;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
pe_header_t ih, oh;
|
|
||||||
pe_section_t *isection;
|
|
||||||
|
|
||||||
static unsigned virta2objnum (unsigned, pe_section_t *, unsigned);
|
|
||||||
unsigned tryremove (unsigned, unsigned);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEDIR_EXPORT = 0,
|
|
||||||
PEDIR_IMPORT = 1,
|
|
||||||
PEDIR_RESOURCE = 2,
|
|
||||||
PEDIR_EXCEPTION = 3, // Exception table
|
|
||||||
PEDIR_SEC = 4, // Certificate table (file pointer)
|
|
||||||
PEDIR_RELOC = 5,
|
|
||||||
PEDIR_DEBUG = 6,
|
|
||||||
PEDIR_COPYRIGHT = 7, // Architecture-specific data
|
|
||||||
PEDIR_GLOBALPTR = 8, // Global pointer
|
|
||||||
PEDIR_TLS = 9,
|
|
||||||
PEDIR_LOADCONF = 10, // Load Config Table
|
|
||||||
PEDIR_BOUNDIM = 11,
|
|
||||||
PEDIR_IAT = 12,
|
|
||||||
PEDIR_DELAYIMP = 13, // Delay Import Descriptor
|
|
||||||
PEDIR_COMRT = 14 // Com+ Runtime Header
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEFL_CODE = 0x20,
|
|
||||||
PEFL_DATA = 0x40,
|
|
||||||
PEFL_BSS = 0x80,
|
|
||||||
PEFL_INFO = 0x200,
|
|
||||||
PEFL_EXTRELS = 0x01000000, // extended relocations
|
|
||||||
PEFL_DISCARD = 0x02000000,
|
|
||||||
PEFL_NOCACHE = 0x04000000,
|
|
||||||
PEFL_NOPAGE = 0x08000000,
|
|
||||||
PEFL_SHARED = 0x10000000,
|
|
||||||
PEFL_EXEC = 0x20000000,
|
|
||||||
PEFL_READ = 0x40000000,
|
|
||||||
PEFL_WRITE = 0x80000000
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RELOCS_STRIPPED = 0x0001,
|
|
||||||
EXECUTABLE = 0x0002,
|
|
||||||
LNUM_STRIPPED = 0x0004,
|
|
||||||
LSYMS_STRIPPED = 0x0008,
|
|
||||||
AGGRESSIVE_TRIM = 0x0010,
|
|
||||||
TWO_GIGS_AWARE = 0x0020,
|
|
||||||
FLITTLE_ENDIAN = 0x0080,
|
|
||||||
BITS_32_MACHINE = 0x0100,
|
|
||||||
DEBUG_STRIPPED = 0x0200,
|
|
||||||
REMOVABLE_SWAP = 0x0400,
|
|
||||||
SYSTEM_PROGRAM = 0x1000,
|
|
||||||
DLL_FLAG = 0x2000,
|
|
||||||
FBIG_ENDIAN = 0x8000
|
|
||||||
};
|
|
||||||
|
|
||||||
// predefined resource types
|
|
||||||
enum {
|
|
||||||
RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING,
|
|
||||||
RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE,
|
|
||||||
RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE,
|
|
||||||
RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML,
|
|
||||||
RT_MANIFEST, RT_LAST
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+23
-20
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_com.h"
|
#include "p_com.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_com.h"
|
#include "stub/i086-dos16.com.h"
|
||||||
|
|
||||||
//#define TESTING
|
//#define TESTING
|
||||||
|
|
||||||
@@ -98,7 +99,6 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
upx_byte *loader, int lsize,
|
upx_byte *loader, int lsize,
|
||||||
unsigned calls)
|
unsigned calls)
|
||||||
{
|
{
|
||||||
const int filter_id = ph.filter;
|
|
||||||
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 < 256);
|
assert(e_len > 0 && e_len < 256);
|
||||||
@@ -111,22 +111,18 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
if (upper_end + stacksize > 0xfffe)
|
if (upper_end + stacksize > 0xfffe)
|
||||||
throwCantPack("file is too big for dos/com");
|
throwCantPack("file is too big for dos/com");
|
||||||
|
|
||||||
if (filter_id)
|
linker->defineSymbol("calltrick_calls", calls);
|
||||||
{
|
linker->defineSymbol("sp_limit", upper_end + stacksize);
|
||||||
assert(calls > 0);
|
linker->defineSymbol("bytes_to_copy", ph.c_len + lsize);
|
||||||
patch_le16(loader,lsize,"CT",calls);
|
linker->defineSymbol("copy_source", ph.c_len + lsize + 0x100);
|
||||||
}
|
linker->defineSymbol("copy_destination", upper_end);
|
||||||
|
linker->defineSymbol("COMCUTPO", ph.u_len + ph.overlap_overhead);
|
||||||
|
|
||||||
|
linker->relocate();
|
||||||
|
loader = getLoader();
|
||||||
|
|
||||||
|
// some day we could use the relocation stuff for patchPackHeader too
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
// NOTE: Depends on: decompr_start == cutpoint+1 !!!
|
|
||||||
patch_le16(loader,e_len,"JM",upper_end - 0xff - d_len - getLoaderSection("UPX1HEAD"));
|
|
||||||
loader[getLoaderSectionStart("COMSUBSI") - 1] = (upx_byte) -e_len;
|
|
||||||
patch_le16(loader,e_len,"DI",upper_end);
|
|
||||||
patch_le16(loader,e_len,"SI",ph.c_len + lsize + 0x100);
|
|
||||||
patch_le16(loader,e_len,"CX",ph.c_len + lsize);
|
|
||||||
patch_le16(loader,e_len,"SP",upper_end + stacksize);
|
|
||||||
|
|
||||||
// write loader + compressed file
|
// write loader + compressed file
|
||||||
fo->write(loader,e_len); // entry
|
fo->write(loader,e_len); // entry
|
||||||
fo->write(obuf,ph.c_len);
|
fo->write(obuf,ph.c_len);
|
||||||
@@ -142,7 +138,7 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
int PackCom::buildLoader(const Filter *ft)
|
int PackCom::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
||||||
addLoader("COMMAIN1,COMSUBSI",
|
addLoader("COMMAIN1",
|
||||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
||||||
"COMPSHDI",
|
"COMPSHDI",
|
||||||
ft->id ? "COMCALLT" : "",
|
ft->id ? "COMCALLT" : "",
|
||||||
@@ -150,7 +146,7 @@ int PackCom::buildLoader(const Filter *ft)
|
|||||||
ft->id ? "NRVDDONE" : "NRVDRETU",
|
ft->id ? "NRVDDONE" : "NRVDRETU",
|
||||||
"NRVDECO1",
|
"NRVDECO1",
|
||||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||||
"NRVDECO2,NRV2B169",
|
"NRVDECO2",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -158,6 +154,7 @@ int PackCom::buildLoader(const Filter *ft)
|
|||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addFilter16(ft->id);
|
addFilter16(ft->id);
|
||||||
}
|
}
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +267,12 @@ void PackCom::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackCom::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -53,6 +53,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
|||||||
+66
-21
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,11 +31,12 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_djgpp2.h"
|
#include "p_djgpp2.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_djgpp2.h"
|
#include "stub/i386-dos32.djgpp2.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/stubify.h"
|
#include "stub/i386-dos32.djgpp2-stubify.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -82,6 +83,12 @@ unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackDjgpp2::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackDjgpp2::buildLoader(const Filter *ft)
|
int PackDjgpp2::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
@@ -89,7 +96,9 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
|||||||
addLoader("IDENTSTR,DJ2MAIN1",
|
addLoader("IDENTSTR,DJ2MAIN1",
|
||||||
ft->id ? "DJCALLT1" : "",
|
ft->id ? "DJCALLT1" : "",
|
||||||
"DJ2MAIN2",
|
"DJ2MAIN2",
|
||||||
getDecompressor(),
|
ph.method == M_LZMA ? "LZMA_INIT_STACK" : "",
|
||||||
|
getDecompressorSections(),
|
||||||
|
ph.method == M_LZMA ? "LZMA_DONE_STACK" : "",
|
||||||
"DJ2BSS00",
|
"DJ2BSS00",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
@@ -99,7 +108,8 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
|||||||
addLoader("DJCALLT2", NULL);
|
addLoader("DJCALLT2", NULL);
|
||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("DJRETURN,+40DXXXX,UPX1HEAD", NULL);
|
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +235,29 @@ void PackDjgpp2::stripDebug()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0)
|
||||||
|
return false;
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
|
int const mru = ph.n_mru ? 1+ ph.n_mru : 0;
|
||||||
|
if (mru && mru!=256) {
|
||||||
|
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||||
|
patch_le32(0x80 + (char *)loader, lsize - 0x80, "NMRU", mru - is_pwr2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -290,33 +323,35 @@ 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
|
||||||
compressWithFilters(&ft, 512);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||||
|
|
||||||
// patch coff header #2
|
// patch coff header #2
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
|
assert(lsize % 4 == 0);
|
||||||
text->size = lsize; // new size of .text
|
text->size = lsize; // new size of .text
|
||||||
data->size = ph.c_len; // new size of .data
|
data->size = ph.c_len; // new size of .data
|
||||||
|
|
||||||
if (bss->size < ph.overlap_overhead) // give it a .bss
|
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
|
||||||
bss->size = ph.overlap_overhead;
|
stack = ALIGN_UP(stack, 16);
|
||||||
|
if (bss->size < stack) // give it a .bss
|
||||||
|
bss->size = stack;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
// prepare loader
|
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||||
MemBuffer loader(lsize);
|
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
|
||||||
memcpy(loader, getLoader(), lsize);
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
// patch loader
|
|
||||||
patchPackHeader(loader, lsize);
|
|
||||||
patch_le32(loader, lsize, "ENTR", coff_hdr.a_entry);
|
|
||||||
patchFilter32(loader, lsize, &ft);
|
|
||||||
patch_le32(loader, lsize, "BSSL", ph.overlap_overhead / 4);
|
|
||||||
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
||||||
patch_le32(loader, lsize, "OUTP", text->vaddr - hdrsize);
|
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||||
patch_le32(loader, lsize, "INPP", data->vaddr);
|
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||||
|
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||||
|
defineFilterSymbols(linker, &ft);
|
||||||
|
|
||||||
// we should not overwrite our decompressor during unpacking
|
// we should not overwrite our decompressor during unpacking
|
||||||
// the original coff header (which is put just before the
|
// the original coff header (which is put just before the
|
||||||
@@ -333,9 +368,19 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
memcpy(obuf+data->size, "UPX", 3);
|
memcpy(obuf+data->size, "UPX", 3);
|
||||||
data->size = ALIGN_UP(data->size, 4);
|
data->size = ALIGN_UP(data->size, 4);
|
||||||
|
|
||||||
|
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
|
||||||
|
linker->relocate();
|
||||||
|
|
||||||
|
// prepare loader
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
// write coff header, loader and compressed file
|
// write coff header, loader and compressed file
|
||||||
fo->write(&coff_hdr, sizeof(coff_hdr));
|
fo->write(&coff_hdr, sizeof(coff_hdr));
|
||||||
fo->write(loader, lsize);
|
fo->write(loader, lsize);
|
||||||
|
if (opt->debug.dump_stub_loader)
|
||||||
|
OutputFile::dump(opt->debug.dump_stub_loader, loader, lsize);
|
||||||
fo->write(obuf, data->size);
|
fo->write(obuf, data->size);
|
||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
||||||
@@ -367,7 +412,7 @@ int PackDjgpp2::canUnpack()
|
|||||||
if (is_dlm(fi, coff_offset))
|
if (is_dlm(fi, coff_offset))
|
||||||
throwCantUnpack("can't handle DLM");
|
throwCantUnpack("can't handle DLM");
|
||||||
fi->seek(coff_offset, SEEK_SET);
|
fi->seek(coff_offset, SEEK_SET);
|
||||||
return readPackHeader(1024) ? 1 : -1;
|
return readPackHeader(4096) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -60,6 +60,7 @@ protected:
|
|||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
long coff_offset;
|
long coff_offset;
|
||||||
|
|
||||||
|
|||||||
+81
-43
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
// Some ELF type definitinons
|
// Some ELF type definitinons
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
namespace TT_Elf {
|
namespace N_Elf {
|
||||||
|
|
||||||
// The ELF file header. This appears at the start of every ELF file.
|
// The ELF file header. This appears at the start of every ELF file.
|
||||||
template <class Word, class Addr, class Off, class Half>
|
template <class Word, class Addr, class Off, class Half>
|
||||||
@@ -71,7 +71,12 @@ struct Ehdr
|
|||||||
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_LINUX = 3
|
ELFOSABI_NONE = 0,
|
||||||
|
ELFOSABI_NETBSD = 2,
|
||||||
|
ELFOSABI_LINUX = 3,
|
||||||
|
ELFOSABI_FREEBSD = 9,
|
||||||
|
ELFOSABI_OPENBSD = 12,
|
||||||
|
ELFOSABI_ARM = 97
|
||||||
};
|
};
|
||||||
enum { // e_type
|
enum { // e_type
|
||||||
ET_NONE = 0, /* No file type */
|
ET_NONE = 0, /* No file type */
|
||||||
@@ -111,10 +116,10 @@ struct Dyn
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
} // namespace TT_Elf
|
} // namespace N_Elf
|
||||||
|
|
||||||
|
|
||||||
namespace TT_Elf32 {
|
namespace N_Elf32 {
|
||||||
|
|
||||||
// Program segment header.
|
// Program segment header.
|
||||||
template <class Word, class Addr, class Off>
|
template <class Word, class Addr, class Off>
|
||||||
@@ -133,6 +138,7 @@ struct Phdr
|
|||||||
PT_LOAD = 1, /* Loadable program segment */
|
PT_LOAD = 1, /* Loadable program segment */
|
||||||
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_PHDR = 6, /* Entry for header table itself */
|
PT_PHDR = 6, /* Entry for header table itself */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -192,7 +198,7 @@ struct Shdr
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
template <class TT16, class TT32, class TT64>
|
template <class TT16, class TT32>
|
||||||
struct Sym
|
struct Sym
|
||||||
{
|
{
|
||||||
TT32 st_name; /* symbol name (index into string table) */
|
TT32 st_name; /* symbol name (index into string table) */
|
||||||
@@ -237,9 +243,10 @@ struct Sym
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
} // namespace TT_Elf32
|
} // namespace N_Elf32
|
||||||
|
|
||||||
namespace TT_Elf64 {
|
|
||||||
|
namespace N_Elf64 {
|
||||||
|
|
||||||
// Program segment header.
|
// Program segment header.
|
||||||
template <class Word, class Xword, class Addr, class Off>
|
template <class Word, class Xword, class Addr, class Off>
|
||||||
@@ -307,29 +314,58 @@ struct Shdr
|
|||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
} // namespace TT_Elf64
|
} // namespace N_Elf64
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// now for the actual types
|
// now for the actual types
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<LE32,LE32,LE32,LE16> Elf_LE32_Ehdr;
|
#define P N_BELE_CTP::HostPolicy
|
||||||
typedef TT_Elf32::Phdr<LE32,LE32,LE32> Elf_LE32_Phdr;
|
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf32_Ehdr;
|
||||||
typedef TT_Elf32::Shdr<LE32,LE32,LE32> Elf_LE32_Shdr;
|
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf32_Phdr;
|
||||||
typedef TT_Elf ::Dyn <LE32,LE32> Elf_LE32_Dyn;
|
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf32_Shdr;
|
||||||
typedef TT_Elf32::Sym <LE16,LE32,void> Elf_LE32_Sym;
|
typedef N_Elf ::Dyn <P::U32,P::U32> Elf32_Dyn;
|
||||||
|
typedef N_Elf32::Sym <P::U16,P::U32> Elf32_Sym;
|
||||||
|
#undef P
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<unsigned int,unsigned int,unsigned int,unsigned short> Elf32_Ehdr;
|
#define P N_BELE_CTP::BEPolicy
|
||||||
typedef TT_Elf32::Phdr<unsigned int,unsigned int,unsigned int> Elf32_Phdr;
|
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_BE32_Ehdr;
|
||||||
typedef TT_Elf32::Shdr<unsigned int,unsigned int,unsigned int> Elf32_Shdr;
|
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_BE32_Phdr;
|
||||||
typedef TT_Elf ::Dyn <unsigned int,unsigned int> Elf32_Dyn;
|
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_BE32_Shdr;
|
||||||
typedef TT_Elf32::Sym <unsigned short,unsigned int,void> Elf32_Sym;
|
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_BE32_Dyn;
|
||||||
|
typedef N_Elf32::Sym <P::U16,P::U32> Elf_BE32_Sym;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::LEPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_LE32_Ehdr;
|
||||||
|
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_LE32_Phdr;
|
||||||
|
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_LE32_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_LE32_Dyn;
|
||||||
|
typedef N_Elf32::Sym <P::U16,P::U32> Elf_LE32_Sym;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::HostPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf64_Ehdr;
|
||||||
|
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf64_Phdr;
|
||||||
|
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf64_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U64,P::U64> Elf64_Dyn;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::BEPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_BE64_Ehdr;
|
||||||
|
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Phdr;
|
||||||
|
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_BE64_Dyn;
|
||||||
|
#undef P
|
||||||
|
|
||||||
|
#define P N_BELE_CTP::LEPolicy
|
||||||
|
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_LE64_Ehdr;
|
||||||
|
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Phdr;
|
||||||
|
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Shdr;
|
||||||
|
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_LE64_Dyn;
|
||||||
|
#undef P
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
|
||||||
@@ -337,31 +373,33 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40)
|
|||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Shdr) == 40)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Dyn) == 8)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Sym) == 16)
|
||||||
|
|
||||||
typedef TT_Elf ::Ehdr<LE32,LE64,LE64,LE16> Elf_LE64_Ehdr;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
|
||||||
typedef TT_Elf64::Phdr<LE32,LE64,LE64,LE64> Elf_LE64_Phdr;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
|
||||||
typedef TT_Elf64::Shdr<LE32,LE64,LE64,LE64> Elf_LE64_Shdr;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
||||||
typedef TT_Elf ::Dyn <LE64,LE64> Elf_LE64_Dyn;
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
||||||
typedef TT_Elf ::Ehdr<unsigned int,unsigned long long,
|
|
||||||
unsigned long long,unsigned short> Elf64_Ehdr;
|
|
||||||
typedef TT_Elf64::Phdr<unsigned int,unsigned long long,
|
|
||||||
unsigned long long,unsigned long long> Elf64_Phdr;
|
|
||||||
typedef TT_Elf64::Shdr<unsigned int,unsigned long long,
|
|
||||||
unsigned long long,unsigned long long> Elf64_Shdr;
|
|
||||||
typedef TT_Elf ::Dyn <unsigned long long,unsigned long long> Elf64_Dyn;
|
|
||||||
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
|
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Ehdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Phdr) == 56)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Shdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Dyn) == 16)
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -100,6 +100,7 @@ int PackElks8086::buildLoader(const Filter *ft)
|
|||||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||||
// FIXME
|
// FIXME
|
||||||
UNUSED(ft);
|
UNUSED(ft);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +123,8 @@ void PackElks8086::pack(OutputFile *fo)
|
|||||||
patchPackHeader(loader, lsize);
|
patchPackHeader(loader, lsize);
|
||||||
#if 0
|
#if 0
|
||||||
// FIXME
|
// FIXME
|
||||||
patchFilter32(loader, lsize, &ft);
|
defineFilterSymbols();
|
||||||
|
defineDecompressorSymbols();
|
||||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||||
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||||
|
|||||||
+44
-46
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_exe.h"
|
#include "p_exe.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_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
|
||||||
#define MAXMATCH 0x2000
|
#define MAXMATCH 0x2000
|
||||||
@@ -125,7 +126,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
||||||
"NRV2BEX3",
|
"NRV2BEX3",
|
||||||
ph.c_len > 0xffff ? "N2B64K02" : "",
|
ph.c_len > 0xffff ? "N2B64K02" : "",
|
||||||
"NRV2BEX9,NRV2B16E",
|
"NRV2BEX9",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
else if (ph.method == M_NRV2D_8)
|
else if (ph.method == M_NRV2D_8)
|
||||||
@@ -137,7 +138,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
||||||
"NRV2DEX3",
|
"NRV2DEX3",
|
||||||
ph.c_len > 0xffff ? "N2D64K02" : "",
|
ph.c_len > 0xffff ? "N2D64K02" : "",
|
||||||
"NRV2DEX9,NRV2D16E",
|
"NRV2DEX9",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
else if (ph.method == M_NRV2E_8)
|
else if (ph.method == M_NRV2E_8)
|
||||||
@@ -149,7 +150,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
||||||
"NRV2EEX3",
|
"NRV2EEX3",
|
||||||
ph.c_len > 0xffff ? "N2E64K02" : "",
|
ph.c_len > 0xffff ? "N2E64K02" : "",
|
||||||
"NRV2EEX9,NRV2E16E",
|
"NRV2EEX9",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
@@ -176,6 +177,7 @@ int PackExe::buildLoader(const Filter *)
|
|||||||
"EXERETIP",
|
"EXERETIP",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,8 +413,10 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
ph.u_len = ih_imagesize + relocsize;
|
ph.u_len = ih_imagesize + relocsize;
|
||||||
// prepare filter
|
// prepare filter
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress
|
// compress (max_match = 8192)
|
||||||
compressWithFilters(&ft, 32, 0, NULL, 0, MAXMATCH);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = MAXMATCH;
|
||||||
|
compressWithFilters(&ft, 32, 0, NULL, &cconf);
|
||||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||||
|
|
||||||
@@ -480,21 +484,27 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
extra_info[eisize++] = (unsigned char) flag;
|
extra_info[eisize++] = (unsigned char) flag;
|
||||||
|
|
||||||
|
linker->defineSymbol("original_cs", ih.cs);
|
||||||
|
linker->defineSymbol("original_ip", ih.ip);
|
||||||
|
linker->defineSymbol("original_sp", ih.sp);
|
||||||
|
linker->defineSymbol("original_ss", ih.ss);
|
||||||
|
linker->defineSymbol("reloc_size",
|
||||||
|
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
|
||||||
|
>= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||||
|
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
|
||||||
|
linker->defineSymbol("decompressor_entry", (packedsize & 15) + 1);
|
||||||
|
|
||||||
// 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 = find_le32(loader,lsize,get_le32("IPCS"));
|
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
||||||
patch_le32(loader,lsize,get_le32("IPCS"), ih.cs*0x10000 + ih.ip);
|
|
||||||
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
|
||||||
{
|
{
|
||||||
patch_le16(loader,lsize,"IP",ih.ip);
|
|
||||||
if (ih.cs)
|
|
||||||
patch_le16(loader,lsize,"CS",ih.cs);
|
|
||||||
oh.relocs = 0;
|
oh.relocs = 0;
|
||||||
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
||||||
}
|
}
|
||||||
@@ -503,46 +513,28 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
||||||
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
||||||
|
|
||||||
if (flag & SP)
|
linker->defineSymbol("destination_segment", oh.ss - ph.c_len / 16 - e_len / 16);
|
||||||
patch_le16(loader,lsize,"SP",ih.sp);
|
linker->defineSymbol("source_segment", e_len / 16 + (copysize - firstcopy) / 16);
|
||||||
if (flag & SS)
|
linker->defineSymbol("copy_offset", firstcopy - 2);
|
||||||
patch_le16(loader,lsize,"SS",ih.ss);
|
linker->defineSymbol("words_to_copy",firstcopy / 2);
|
||||||
if (relocsize)
|
|
||||||
patch_le16(loader,lsize,"RS",(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
|
|
||||||
|
|
||||||
patchPackHeader(loader,e_len);
|
linker->defineSymbol("exe_stack_sp", oh.sp);
|
||||||
|
linker->defineSymbol("exe_stack_ss", oh.ss);
|
||||||
patch_le16(loader,e_len,"BX",0x800F + 0x10*((packedsize&15)+1) - 0x10);
|
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||||
patch_le16(loader,e_len,"BP",(packedsize&15)+1);
|
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||||
|
linker->defineSymbol("orig_strategy", get_le16(ibuf + 6));
|
||||||
unsigned destpara = oh.ss - ph.c_len/16;
|
|
||||||
patch_le16(loader,e_len,"ES",destpara-e_len/16);
|
|
||||||
patch_le16(loader,e_len,"DS",e_len/16+(copysize-firstcopy)/16);
|
|
||||||
patch_le16(loader,e_len,"SI",firstcopy-2);
|
|
||||||
patch_le16(loader,e_len,"CX",firstcopy/2);
|
|
||||||
|
|
||||||
// finish --stub support
|
|
||||||
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
|
|
||||||
// throwCantPack("FIXME");
|
|
||||||
|
|
||||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||||
oh.m512 = outputlen & 511;
|
oh.m512 = outputlen & 511;
|
||||||
oh.p512 = (outputlen + 511) >> 9;
|
oh.p512 = (outputlen + 511) >> 9;
|
||||||
|
|
||||||
oh.ip = 0;
|
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0;
|
||||||
if (device_driver)
|
|
||||||
{
|
|
||||||
patch_le16(loader, e_len, "OP", oh.sp);
|
|
||||||
patch_le16(loader, e_len, "OS", oh.ss);
|
|
||||||
// copy .sys header
|
|
||||||
memcpy(loader + 4, ibuf + 4, 2);
|
|
||||||
memcpy(loader + 8, ibuf + 8, 2);
|
|
||||||
// copy original strategy
|
|
||||||
memcpy(loader + 10, ibuf + 6, 2);
|
|
||||||
oh.ip = getLoaderSection("EXEENTRY") - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//fprintf(stderr,"\ne_len=%x d_len=%x clen=%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);
|
linker->relocate();
|
||||||
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
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);
|
||||||
|
|
||||||
// write header + write loader + compressed file
|
// write header + write loader + compressed file
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
@@ -716,6 +708,12 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackExe::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -69,6 +69,7 @@ protected:
|
|||||||
|
|
||||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
struct exe_header_t
|
struct exe_header_t
|
||||||
{
|
{
|
||||||
|
|||||||
+955
-716
File diff suppressed because it is too large
Load Diff
+151
-78
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 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
|
||||||
@@ -51,19 +51,31 @@ protected:
|
|||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
//virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
||||||
|
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
) = 0;
|
) = 0;
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
virtual void unpack(OutputFile *fo) = 0;
|
virtual void unpack(OutputFile *fo) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
char *file_image; // if ET_DYN investigation
|
||||||
|
char const *dynstr; // from DT_STRTAB
|
||||||
|
|
||||||
unsigned sz_phdrs; // sizeof Phdr[]
|
unsigned sz_phdrs; // sizeof Phdr[]
|
||||||
unsigned sz_elf_hdrs; // all Elf headers
|
unsigned sz_elf_hdrs; // all Elf headers
|
||||||
|
unsigned sz_pack2; // after pack2(), before loader
|
||||||
|
|
||||||
|
unsigned short e_machine;
|
||||||
|
unsigned char ei_class;
|
||||||
|
unsigned char ei_data;
|
||||||
|
unsigned char ei_osabi;
|
||||||
|
char const *osabi_note;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PackLinuxElf32 : public PackLinuxElf
|
class PackLinuxElf32 : public PackLinuxElf
|
||||||
@@ -73,15 +85,19 @@ public:
|
|||||||
PackLinuxElf32(InputFile *f);
|
PackLinuxElf32(InputFile *f);
|
||||||
virtual ~PackLinuxElf32();
|
virtual ~PackLinuxElf32();
|
||||||
protected:
|
protected:
|
||||||
virtual int checkEhdr(
|
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||||
Elf32_Ehdr const *ehdr,
|
virtual bool canPack();
|
||||||
unsigned char e_machine,
|
|
||||||
unsigned char ei_class,
|
// These ARM routines are essentially common to big/little endian,
|
||||||
unsigned char ei_data) const;
|
// but the class hierarchy splits after this class.
|
||||||
|
virtual int ARM_buildLoader(Filter const *ft, bool isBE);
|
||||||
|
virtual void ARM_defineSymbols(Filter const *ft);
|
||||||
|
virtual void ARM_updateLoader(OutputFile *);
|
||||||
|
virtual void ARM_pack1(OutputFile *, bool isBE);
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
@@ -90,6 +106,13 @@ protected:
|
|||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
virtual int buildLinuxLoader(
|
||||||
|
upx_byte const *const proto, // assembly-only sections
|
||||||
|
unsigned const szproto,
|
||||||
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
|
unsigned const szfold,
|
||||||
|
Filter const *ft
|
||||||
|
);
|
||||||
virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void updateLoader(OutputFile *fo);
|
virtual void updateLoader(OutputFile *fo);
|
||||||
@@ -97,10 +120,19 @@ protected:
|
|||||||
unsigned const e_phnum);
|
unsigned const e_phnum);
|
||||||
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||||
|
|
||||||
|
static unsigned elf_hash(char const *) /*const*/;
|
||||||
|
virtual void const *elf_find_dynamic(unsigned) const;
|
||||||
|
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
||||||
|
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Elf32_Ehdr ehdri; // from input file
|
Elf32_Ehdr ehdri; // from input file
|
||||||
Elf32_Phdr *phdri; // for input file
|
Elf32_Phdr *phdri; // for input file
|
||||||
|
|
||||||
|
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
||||||
|
unsigned int const *hashtab; // from DT_HASH
|
||||||
|
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
struct cprElfHdr1 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[1];
|
Elf32_Phdr phdr[1];
|
||||||
@@ -123,6 +155,14 @@ protected:
|
|||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
cprElfHdr3 elfout;
|
cprElfHdr3 elfout;
|
||||||
|
|
||||||
|
struct Elf32_Note {
|
||||||
|
unsigned namesz; // 8
|
||||||
|
unsigned descsz; // 4
|
||||||
|
unsigned type; // 1
|
||||||
|
char text[0x18 - 4*4]; // "OpenBSD"
|
||||||
|
unsigned end; // 0
|
||||||
|
} elfnote;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -135,15 +175,11 @@ public:
|
|||||||
/*virtual int buildLoader(const Filter *);*/
|
/*virtual int buildLoader(const Filter *);*/
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int checkEhdr(
|
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||||
Elf64_Ehdr const *ehdr,
|
|
||||||
unsigned char e_machine,
|
|
||||||
unsigned char ei_class,
|
|
||||||
unsigned char ei_data) const;
|
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
@@ -152,6 +188,13 @@ protected:
|
|||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
virtual int buildLinuxLoader(
|
||||||
|
upx_byte const *const proto, // assembly-only sections
|
||||||
|
unsigned const szproto,
|
||||||
|
upx_byte const *const fold, // linked assembly + C section
|
||||||
|
unsigned const szfold,
|
||||||
|
Filter const *ft
|
||||||
|
);
|
||||||
virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
|
virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void updateLoader(OutputFile *fo);
|
virtual void updateLoader(OutputFile *fo);
|
||||||
@@ -243,21 +286,11 @@ public:
|
|||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
protected:
|
protected:
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
//virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual int buildLoader(const Filter *);
|
virtual int buildLoader(const Filter *);
|
||||||
virtual int buildLinuxLoader(
|
virtual Linker* newLinker() const;
|
||||||
upx_byte const *const proto, // assembly-only sections
|
virtual void defineSymbols(Filter const *);
|
||||||
unsigned const szproto,
|
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
|
||||||
unsigned const szfold,
|
|
||||||
Filter const *ft
|
|
||||||
);
|
|
||||||
virtual void generateElfHdr(
|
|
||||||
OutputFile *,
|
|
||||||
void const *proto,
|
|
||||||
unsigned const brka
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -273,23 +306,10 @@ public:
|
|||||||
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
||||||
virtual const char *getName() const { return "linux/ElfPPC"; }
|
virtual const char *getName() const { return "linux/ElfPPC"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual bool canPack();
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
|
||||||
virtual int buildLoader(const Filter *);
|
virtual int buildLoader(const Filter *);
|
||||||
virtual int buildLinuxLoader(
|
virtual Linker* newLinker() const;
|
||||||
upx_byte const *const proto, // assembly-only sections
|
|
||||||
unsigned const szproto,
|
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
|
||||||
unsigned const szfold,
|
|
||||||
Filter const *ft
|
|
||||||
);
|
|
||||||
virtual void generateElfHdr(
|
|
||||||
OutputFile *,
|
|
||||||
void const *proto,
|
|
||||||
unsigned const brka
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -302,56 +322,109 @@ class PackLinuxElf32x86 : public PackLinuxElf32Le
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf32x86(InputFile *f);
|
PackLinuxElf32x86(InputFile *f);
|
||||||
virtual ~PackLinuxElf32x86();
|
virtual ~PackLinuxElf32x86();
|
||||||
virtual int getVersion() const { return 13; }
|
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
||||||
virtual const char *getName() const { return "linux/elf386"; }
|
virtual const char *getName() const { return "linux/elf386"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
protected:
|
||||||
virtual bool canUnpackVersion(int version) const
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
{ return (version >= 11); }
|
|
||||||
|
virtual int buildLoader(const Filter *);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackBSDElf32x86 : public PackLinuxElf32x86
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackBSDElf32x86();
|
||||||
|
virtual int getFormat() const { return UPX_F_BSD_ELF_i386; }
|
||||||
|
virtual const char *getName() const { return "BSD/elf386"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
|
||||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
|
||||||
|
|
||||||
virtual void patchLoader();
|
|
||||||
virtual int buildLoader(const Filter *);
|
virtual int buildLoader(const Filter *);
|
||||||
virtual int buildLinuxLoader(
|
};
|
||||||
upx_byte const *const proto, // assembly-only sections
|
|
||||||
unsigned const szproto,
|
class PackFreeBSDElf32x86 : public PackBSDElf32x86
|
||||||
upx_byte const *const fold, // linked assembly + C section
|
{
|
||||||
unsigned const szfold,
|
typedef PackBSDElf32x86 super;
|
||||||
Filter const *ft
|
public:
|
||||||
);
|
PackFreeBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackFreeBSDElf32x86();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackNetBSDElf32x86 : public PackBSDElf32x86
|
||||||
|
{
|
||||||
|
typedef PackBSDElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackNetBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackNetBSDElf32x86();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackOpenBSDElf32x86 : public PackBSDElf32x86
|
||||||
|
{
|
||||||
|
typedef PackBSDElf32x86 super;
|
||||||
|
public:
|
||||||
|
PackOpenBSDElf32x86(InputFile *f);
|
||||||
|
virtual ~PackOpenBSDElf32x86();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual int buildLoader(const Filter *ft);
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
unsigned const brka
|
unsigned const brka
|
||||||
);
|
);
|
||||||
|
|
||||||
Elf32_Ehdr ehdri; // from input file
|
|
||||||
Elf32_Phdr *phdri; // for input file
|
|
||||||
unsigned sz_phdrs; // sizeof Phdr[]
|
|
||||||
|
|
||||||
char *file_image; // if ET_DYN investigation
|
|
||||||
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
|
||||||
unsigned int const *hashtab; // from DT_HASH
|
|
||||||
char const *dynstr; // from DT_STRTAB
|
|
||||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
|
||||||
|
|
||||||
static unsigned elf_hash(char const *) /*const*/;
|
|
||||||
virtual void const *elf_find_dynamic(unsigned) const;
|
|
||||||
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
|
||||||
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
|
||||||
virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
|
|
||||||
unsigned const e_phnum);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// linux/elfarm
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
class PackLinuxElf32armLe : public PackLinuxElf32Le
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32Le super;
|
||||||
|
public:
|
||||||
|
PackLinuxElf32armLe(InputFile *f);
|
||||||
|
virtual ~PackLinuxElf32armLe();
|
||||||
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
|
||||||
|
virtual const char *getName() const { return "linux/armLE"; }
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
virtual int buildLoader(const Filter *);
|
||||||
|
virtual void updateLoader(OutputFile *);
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackLinuxElf32armBe : public PackLinuxElf32Be
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32Be super;
|
||||||
|
public:
|
||||||
|
PackLinuxElf32armBe(InputFile *f);
|
||||||
|
virtual ~PackLinuxElf32armBe();
|
||||||
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
|
||||||
|
virtual const char *getName() const { return "linux/armBE"; }
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
virtual int buildLoader(const Filter *);
|
||||||
|
virtual void updateLoader(OutputFile *);
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
};
|
||||||
|
|
||||||
#endif /*} already included */
|
#endif /*} already included */
|
||||||
|
|
||||||
|
|||||||
+214
-100
@@ -54,10 +54,34 @@
|
|||||||
// linux/386 (generic "execve" format)
|
// linux/386 (generic "execve" format)
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
PackLinuxI386::PackLinuxI386(InputFile *f) : super(f),
|
||||||
|
ei_osabi(Elf32_Ehdr::ELFOSABI_LINUX), osabi_note(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PackBSDI386::PackBSDI386(InputFile *f) : super(f)
|
||||||
|
{
|
||||||
|
// Shell scripts need help specifying the target operating system.
|
||||||
|
// Elf input will override this with .e_ident[EI_OSABI] or PT_NOTE.
|
||||||
|
// [2006-09-27: Today's only runtime stub for shell is for linux.]
|
||||||
|
if (Elf32_Ehdr::ELFOSABI_LINUX==opt->o_unix.osabi0) {
|
||||||
|
// Disallow an incompatibility.
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_NONE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ei_osabi = opt->o_unix.osabi0; // might be ELFOSABI_NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_exec86.h"
|
#include "stub/i386-linux.elf.execve-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_exec86.h"
|
#include "stub/i386-linux.elf.execve-fold.h"
|
||||||
|
|
||||||
|
static const
|
||||||
|
#include "stub/i386-bsd.elf.execve-entry.h"
|
||||||
|
static const
|
||||||
|
#include "stub/i386-bsd.elf.execve-fold.h"
|
||||||
|
|
||||||
|
|
||||||
const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
||||||
@@ -69,14 +93,9 @@ const int *PackLinuxI386::getFilters() const
|
|||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x49, 0x46,
|
0x49, 0x46,
|
||||||
// FIXME 2002-11-11: We use stub/fold_exec86.asm, which calls the
|
|
||||||
// decompressor multiple times, and unfilter is independent of decompress.
|
|
||||||
// Currently only filters 0x49, 0x46, 0x80..0x87 can handle this;
|
|
||||||
// and 0x80..0x87 are regarded as "untested".
|
|
||||||
#if 0
|
|
||||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||||
#endif
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// 0x80..0x87 are regarded as "untested".
|
||||||
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
||||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||||
#endif
|
#endif
|
||||||
@@ -84,6 +103,27 @@ const int *PackLinuxI386::getFilters() const
|
|||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_stub_brk(Elf_LE32_Phdr *const phdr1, unsigned brka)
|
||||||
|
{
|
||||||
|
#define PAGE_MASK (~0ul<<12)
|
||||||
|
// linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
|
||||||
|
unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);
|
||||||
|
phdr1->p_type = PT_LOAD; // be sure
|
||||||
|
phdr1->p_offset = ~PAGE_MASK & brkb;
|
||||||
|
phdr1->p_vaddr = brkb;
|
||||||
|
phdr1->p_paddr = brkb;
|
||||||
|
phdr1->p_filesz = 0;
|
||||||
|
phdr1->p_memsz = 0;
|
||||||
|
if (0==phdr1->p_flags) {
|
||||||
|
phdr1->p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;
|
||||||
|
}
|
||||||
|
if (0==phdr1->p_align) {
|
||||||
|
phdr1->p_align = 0x1000;
|
||||||
|
}
|
||||||
|
#undef PAGE_MASK
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PackLinuxI386::generateElfHdr(
|
PackLinuxI386::generateElfHdr(
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
@@ -91,7 +131,6 @@ PackLinuxI386::generateElfHdr(
|
|||||||
unsigned const brka
|
unsigned const brka
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout;
|
|
||||||
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
|
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
|
||||||
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
||||||
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
||||||
@@ -111,32 +150,19 @@ PackLinuxI386::generateElfHdr(
|
|||||||
|
|
||||||
// Info for OS kernel to set the brk()
|
// Info for OS kernel to set the brk()
|
||||||
if (brka) {
|
if (brka) {
|
||||||
#define PAGE_MASK (~0ul<<12)
|
set_stub_brk(&h2->phdr[1], brka);
|
||||||
// linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
|
|
||||||
unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);
|
|
||||||
h2->phdr[1].p_type = PT_LOAD; // be sure
|
|
||||||
h2->phdr[1].p_offset = ~PAGE_MASK & brkb;
|
|
||||||
h2->phdr[1].p_vaddr = brkb;
|
|
||||||
h2->phdr[1].p_paddr = brkb;
|
|
||||||
h2->phdr[1].p_filesz = 0;
|
|
||||||
h2->phdr[1].p_memsz = 0;
|
|
||||||
if (0==h2->phdr[1].p_flags) {
|
|
||||||
h2->phdr[1].p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;
|
|
||||||
}
|
|
||||||
if (0==h2->phdr[1].p_align) {
|
|
||||||
h2->phdr[1].p_align = 0x1000;
|
|
||||||
}
|
|
||||||
#undef PAGE_MASK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ph.format==UPX_F_LINUX_i386 ) {
|
if (ph.format==UPX_F_LINUX_i386
|
||||||
assert(h1->ehdr.e_phnum==1);
|
|| ph.format==UPX_F_LINUX_SH_i386
|
||||||
memset(&h1->linfo, 0, sizeof(h1->linfo));
|
|| ph.format==UPX_F_BSD_i386
|
||||||
fo->write(h1, sizeof(*h1));
|
) {
|
||||||
}
|
// SELinux, PAx, grSecurity demand no PF_W if PF_X.
|
||||||
else if (ph.format==UPX_F_LINUX_SH_i386) {
|
// kernel-2.6.12-2.3.legacy_FC3 has a bug which demands
|
||||||
assert(h2->ehdr.e_phnum==1);
|
// a PT_LOAD with PF_W, else SIGSEGV when clearing page fragment
|
||||||
h2->ehdr.e_phnum = 1;
|
// on low page of ".bss", which is the high page of .text.
|
||||||
|
// So the minimum number of PT_LOAD is 2.
|
||||||
|
assert(h2->ehdr.e_phnum==2);
|
||||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||||
fo->write(h2, sizeof(*h2));
|
fo->write(h2, sizeof(*h2));
|
||||||
}
|
}
|
||||||
@@ -159,6 +185,15 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
|
|||||||
generateElfHdr(fo, linux_i386exec_fold, 0);
|
generateElfHdr(fo, linux_i386exec_fold, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackBSDI386::pack1(OutputFile *fo, Filter &)
|
||||||
|
{
|
||||||
|
// create a pseudo-unique program id for our paranoid stub
|
||||||
|
progid = getRandomId();
|
||||||
|
|
||||||
|
generateElfHdr(fo, bsd_i386exec_fold, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
||||||
{
|
{
|
||||||
@@ -166,10 +201,11 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||||
sizeof(l_info) +
|
sizeof(l_info) +
|
||||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
||||||
unsigned len = fo->getBytesWritten();
|
unsigned nw = fo->getBytesWritten();
|
||||||
set_native32(&elfout.phdr[0].p_filesz, len);
|
elfout.phdr[0].p_filesz = nw;
|
||||||
|
nw = -(-elfout.phdr[0].p_align & -nw); // ALIGN_UP
|
||||||
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
||||||
|
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
|
||||||
|
|
||||||
#if 0 // {
|
#if 0 // {
|
||||||
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
||||||
@@ -186,38 +222,38 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
|||||||
|
|
||||||
// Supply a "linking view" that covers everything,
|
// Supply a "linking view" that covers everything,
|
||||||
// so that 'strip' does not omit everything.
|
// so that 'strip' does not omit everything.
|
||||||
Elf32_Shdr shdr;
|
Elf_LE32_Shdr shdr;
|
||||||
// The section header string table.
|
// The section header string table.
|
||||||
char const shstrtab[] = "\0.\0.shstrtab";
|
char const shstrtab[] = "\0.\0.shstrtab";
|
||||||
|
|
||||||
unsigned eod = elfout.phdr[0].p_filesz;
|
unsigned eod = elfout.phdr[0].p_filesz;
|
||||||
set_native32(&elfout.ehdr.e_shoff, eod);
|
elfout.ehdr.e_shoff = eod;
|
||||||
set_native16(&elfout.ehdr.e_shentsize, sizeof(shdr));
|
elfout.ehdr.e_shentsize = sizeof(shdr);
|
||||||
set_native16(&elfout.ehdr.e_shnum, 3);
|
elfout.ehdr.e_shnum = 3;
|
||||||
set_native16(&elfout.ehdr.e_shstrndx, 2);
|
elfout.ehdr.e_shstrndx = 2;
|
||||||
|
|
||||||
// An empty Elf32_Shdr for space as a null index.
|
// An empty Elf32_Shdr for space as a null index.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_NULL);
|
shdr.sh_type = Elf32_Shdr::SHT_NULL;
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// Cover all the bits we need at runtime.
|
// Cover all the bits we need at runtime.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 1);
|
shdr.sh_name = 1;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_PROGBITS);
|
shdr.sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||||
set_native32(&shdr.sh_flags, Elf32_Shdr::SHF_ALLOC);
|
shdr.sh_flags = Elf32_Shdr::SHF_ALLOC;
|
||||||
set_native32(&shdr.sh_addr, elfout.phdr[0].p_vaddr);
|
shdr.sh_addr = elfout.phdr[0].p_vaddr;
|
||||||
set_native32(&shdr.sh_offset, overlay_offset);
|
shdr.sh_offset = overlay_offset;
|
||||||
set_native32(&shdr.sh_size, eod - overlay_offset);
|
shdr.sh_size = eod - overlay_offset;
|
||||||
set_native32(&shdr.sh_addralign, 4096);
|
shdr.sh_addralign = 4096;
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
// A section header for the section header string table.
|
// A section header for the section header string table.
|
||||||
memset(&shdr, 0, sizeof(shdr));
|
memset(&shdr, 0, sizeof(shdr));
|
||||||
set_native32(&shdr.sh_name, 3);
|
shdr.sh_name = 3;
|
||||||
set_native32(&shdr.sh_type, Elf32_Shdr::SHT_STRTAB);
|
shdr.sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||||
set_native32(&shdr.sh_offset, 3*sizeof(shdr) + eod);
|
shdr.sh_offset = 3*sizeof(shdr) + eod;
|
||||||
set_native32(&shdr.sh_size, sizeof(shstrtab));
|
shdr.sh_size = sizeof(shstrtab);
|
||||||
fo->write(&shdr, sizeof(shdr));
|
fo->write(&shdr, sizeof(shdr));
|
||||||
|
|
||||||
fo->write(shstrtab, sizeof(shstrtab));
|
fo->write(shstrtab, sizeof(shstrtab));
|
||||||
@@ -251,6 +287,11 @@ umax(unsigned a, unsigned b)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackLinuxI386::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PackLinuxI386::buildLinuxLoader(
|
PackLinuxI386::buildLinuxLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
@@ -262,7 +303,6 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
{
|
{
|
||||||
initLoader(proto, szproto);
|
initLoader(proto, szproto);
|
||||||
|
|
||||||
struct b_info h; memset(&h, 0, sizeof(h));
|
|
||||||
unsigned fold_hdrlen = 0;
|
unsigned fold_hdrlen = 0;
|
||||||
if (0 < szfold) {
|
if (0 < szfold) {
|
||||||
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
||||||
@@ -272,40 +312,29 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||||
}
|
}
|
||||||
h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen);
|
|
||||||
h.b_method = (unsigned char) ph.method;
|
|
||||||
h.b_ftid = (unsigned char) ph.filter;
|
|
||||||
h.b_cto8 = (unsigned char) ph.filter_cto;
|
|
||||||
}
|
|
||||||
unsigned char const *const uncLoader = fold_hdrlen + fold;
|
|
||||||
|
|
||||||
unsigned char *const cprLoader = new unsigned char[h.sz_unc];
|
|
||||||
if (0 < szfold) {
|
|
||||||
unsigned sz_cpr = h.sz_unc;
|
|
||||||
memcpy(cprLoader, uncLoader, sz_cpr);
|
|
||||||
h.sz_cpr = sz_cpr;
|
|
||||||
}
|
}
|
||||||
// This adds the definition to the "library", to be used later.
|
// This adds the definition to the "library", to be used later.
|
||||||
linker->addSection("FOLDEXEC", cprLoader, h.sz_cpr);
|
// NOTE: the stub is NOT compressed! The savings is not worth it.
|
||||||
delete [] cprLoader;
|
linker->addSection("FOLDEXEC", fold + fold_hdrlen, szfold - fold_hdrlen, 0);
|
||||||
|
|
||||||
n_mru = ft->n_mru;
|
n_mru = ft->n_mru;
|
||||||
|
|
||||||
// Here is a quick summary of the format of the output file:
|
// Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp */
|
||||||
linker->setLoaderAlignOffset(
|
// // Here is a quick summary of the format of the output file:
|
||||||
// Elf32_Edhr
|
// linker->setLoaderAlignOffset(
|
||||||
sizeof(elfout.ehdr) +
|
// // Elf32_Edhr
|
||||||
// Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
// sizeof(elfout.ehdr) +
|
||||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
// // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
||||||
// checksum UPX! lsize version format
|
// (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||||
sizeof(l_info) +
|
// // checksum UPX! lsize version format
|
||||||
// PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
// sizeof(l_info) +
|
||||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
// // PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
||||||
// p_progid, p_filesize, p_blocksize
|
// ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
||||||
sizeof(p_info) +
|
// // p_progid, p_filesize, p_blocksize
|
||||||
// compressed data
|
// sizeof(p_info) +
|
||||||
b_len + ph.c_len );
|
// // compressed data
|
||||||
// entry to stub
|
// b_len + ph.c_len );
|
||||||
|
// // entry to stub
|
||||||
addLoader("LEXEC000", NULL);
|
addLoader("LEXEC000", NULL);
|
||||||
|
|
||||||
if (ft->id) {
|
if (ft->id) {
|
||||||
@@ -314,7 +343,11 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addLoader("LEXEC010", NULL);
|
addLoader("LEXEC010", NULL);
|
||||||
addLoader(getDecompressor(), NULL);
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LEXEC015", NULL);
|
addLoader("LEXEC015", NULL);
|
||||||
if (ft->id) {
|
if (ft->id) {
|
||||||
{ // decompr, unfilter not separate
|
{ // decompr, unfilter not separate
|
||||||
@@ -339,16 +372,28 @@ PackLinuxI386::buildLinuxLoader(
|
|||||||
addLoader("IDENTSTR", NULL);
|
addLoader("IDENTSTR", NULL);
|
||||||
addLoader("LEXEC020", NULL);
|
addLoader("LEXEC020", NULL);
|
||||||
addLoader("FOLDEXEC", NULL);
|
addLoader("FOLDEXEC", NULL);
|
||||||
|
freezeLoader();
|
||||||
char *ptr_cto = (char *)const_cast<unsigned char *>(getLoader());
|
if (ph.method == M_LZMA) {
|
||||||
int sz_cto = getLoaderSize();
|
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||||
if (0x20==(ft->id & 0xF0) || 0x30==(ft->id & 0xF0)) { // push byte '?' ; cto8
|
unsigned const properties = // lc, lp, pb, dummy
|
||||||
patch_le16(ptr_cto, sz_cto, "\x6a?", 0x6a + (ft->cto << 8));
|
(res->lit_context_bits << 0) |
|
||||||
checkPatch(NULL, 0, 0, 0); // reset
|
(res->lit_pos_bits << 8) |
|
||||||
|
(res->pos_bits << 16);
|
||||||
|
linker->defineSymbol("lzma_properties", properties);
|
||||||
|
// -2 for properties
|
||||||
|
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||||
|
linker->defineSymbol("lzma_u_len", ph.u_len);
|
||||||
|
unsigned const stack = getDecompressorWrkmemSize();
|
||||||
|
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
||||||
}
|
}
|
||||||
// PackHeader and overlay_offset at the end of the output file,
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
// after the compressed data.
|
int const mru = ft->n_mru ? 1+ ft->n_mru : 0;
|
||||||
|
if (mru && mru!=256) {
|
||||||
|
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||||
|
linker->defineSymbol("NMRU", mru - is_pwr2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
linker->relocate();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,6 +417,26 @@ PackLinuxI386::buildLoader(Filter const *ft)
|
|||||||
buf, sz_fold, ft );
|
buf, sz_fold, ft );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PackBSDI386::buildLoader(Filter const *ft)
|
||||||
|
{
|
||||||
|
unsigned const sz_fold = sizeof(bsd_i386exec_fold);
|
||||||
|
MemBuffer buf(sz_fold);
|
||||||
|
memcpy(buf, bsd_i386exec_fold, sz_fold);
|
||||||
|
|
||||||
|
// patch loader
|
||||||
|
// note: we only can use /proc/<pid>/fd when exetype > 0.
|
||||||
|
// also, we sleep much longer when compressing a script.
|
||||||
|
checkPatch(NULL, 0, 0, 0); // reset
|
||||||
|
patch_le32(buf,sz_fold,"UPX4",exetype > 0 ? 3 : 15); // sleep time
|
||||||
|
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||||
|
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||||
|
|
||||||
|
return buildLinuxLoader(
|
||||||
|
bsd_i386exec_loader, sizeof(bsd_i386exec_loader),
|
||||||
|
buf, sz_fold, ft );
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: getLoaderPrefixSize is unused?
|
// FIXME: getLoaderPrefixSize is unused?
|
||||||
int PackLinuxI386::getLoaderPrefixSize() const
|
int PackLinuxI386::getLoaderPrefixSize() const
|
||||||
{
|
{
|
||||||
@@ -437,6 +502,7 @@ bool PackLinuxI386::canPack()
|
|||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
unsigned char *buf = ehdr.e_ident;
|
unsigned char *buf = ehdr.e_ident;
|
||||||
|
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ehdr, sizeof(ehdr));
|
fi->readx(&ehdr, sizeof(ehdr));
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
|
|
||||||
@@ -444,12 +510,58 @@ bool PackLinuxI386::canPack()
|
|||||||
const unsigned l = get_le32(buf);
|
const unsigned l = get_le32(buf);
|
||||||
|
|
||||||
int elf = checkEhdr(&ehdr);
|
int elf = checkEhdr(&ehdr);
|
||||||
if (elf >= 0)
|
if (elf >= 0) {
|
||||||
{
|
|
||||||
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
||||||
// so we only handle them here if force_execve
|
// so we only handle them here if force_execve
|
||||||
if (elf == 0 && opt->o_unix.force_execve)
|
if (elf == 0 && opt->o_unix.force_execve) {
|
||||||
exetype = 1;
|
exetype = 1;
|
||||||
|
|
||||||
|
unsigned osabi0 = ehdr.e_ident[Elf32_Ehdr::EI_OSABI];
|
||||||
|
switch (osabi0) {
|
||||||
|
case Elf32_Ehdr::ELFOSABI_LINUX:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_FREEBSD:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_NETBSD:
|
||||||
|
case Elf32_Ehdr::ELFOSABI_OPENBSD:
|
||||||
|
ei_osabi = osabi0; // Proudly declares its osabi in Ehdr.
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unsigned const e_phnum = get_native16(&ehdr.e_phnum);
|
||||||
|
if (e_phnum<=(512/sizeof(Elf32_Phdr))) {
|
||||||
|
char buf2[512];
|
||||||
|
fi->seek(get_native32(&ehdr.e_phoff), SEEK_SET);
|
||||||
|
fi->readx(buf2, sizeof(buf2));
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
|
Elf32_Phdr const *phdr = (Elf32_Phdr const *)buf2;
|
||||||
|
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||||
|
if (phdr->PT_NOTE == get_native32(&phdr->p_type)) {
|
||||||
|
unsigned const offset = get_native32(&phdr->p_offset);
|
||||||
|
struct Elf32_Note note; memset(¬e, 0, sizeof(note));
|
||||||
|
fi->seek(offset, SEEK_SET);
|
||||||
|
fi->readx(¬e, sizeof(note));
|
||||||
|
fi->seek(0, SEEK_SET);
|
||||||
|
if (4==get_native32(¬e.descsz)
|
||||||
|
&& 1==get_native32(¬e.type)
|
||||||
|
&& 0==note.end ) {
|
||||||
|
if (0==strcmp("NetBSD", (char const *)¬e.text)) {
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0==strcmp("OpenBSD", (char const *)¬e.text)) {
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (UPX_F_BSD_i386==getFormat()
|
||||||
|
&& !(Elf32_Ehdr::ELFOSABI_FREEBSD==ei_osabi
|
||||||
|
|| Elf32_Ehdr::ELFOSABI_NETBSD ==ei_osabi
|
||||||
|
|| Elf32_Ehdr::ELFOSABI_OPENBSD==ei_osabi )) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
||||||
{
|
{
|
||||||
@@ -458,15 +570,17 @@ bool PackLinuxI386::canPack()
|
|||||||
// FIXME: N_TRSIZE, N_DRSIZE
|
// FIXME: N_TRSIZE, N_DRSIZE
|
||||||
// FIXME: check for aout shared libraries
|
// FIXME: check for aout shared libraries
|
||||||
}
|
}
|
||||||
#if defined(__linux__)
|
else { // shell scripts and other interpreters
|
||||||
// only compress scripts when running under Linux
|
if (Elf32_Ehdr::ELFOSABI_LINUX!=ei_osabi) {
|
||||||
|
return false; // so far, only Linux has runtime stub for shell
|
||||||
|
}
|
||||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||||
exetype = -1;
|
exetype = -1;
|
||||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||||
exetype = -1;
|
exetype = -1;
|
||||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||||
exetype = -2;
|
exetype = -2;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
return super::canPack();
|
return super::canPack();
|
||||||
}
|
}
|
||||||
@@ -477,7 +591,7 @@ void PackLinuxI386::patchLoader() { }
|
|||||||
|
|
||||||
void PackLinuxI386::patchLoaderChecksum()
|
void PackLinuxI386::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +
|
l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +
|
||||||
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
||||||
// checksum for loader + p_info
|
// checksum for loader + p_info
|
||||||
|
|||||||
+33
-9
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,7 +41,7 @@ class PackLinuxI386 : public PackUnixLe32
|
|||||||
{
|
{
|
||||||
typedef PackUnixLe32 super;
|
typedef PackUnixLe32 super;
|
||||||
public:
|
public:
|
||||||
PackLinuxI386(InputFile *f) : super(f) { }
|
PackLinuxI386(InputFile *f);
|
||||||
virtual void generateElfHdr(
|
virtual void generateElfHdr(
|
||||||
OutputFile *,
|
OutputFile *,
|
||||||
void const *proto,
|
void const *proto,
|
||||||
@@ -62,6 +62,7 @@ protected:
|
|||||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
|
||||||
// loader util
|
// loader util
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
virtual int getLoaderPrefixSize() const;
|
virtual int getLoaderPrefixSize() const;
|
||||||
virtual int buildLinuxLoader(
|
virtual int buildLinuxLoader(
|
||||||
upx_byte const *const proto, // assembly-only sections
|
upx_byte const *const proto, // assembly-only sections
|
||||||
@@ -86,31 +87,54 @@ protected:
|
|||||||
unsigned n_mru;
|
unsigned n_mru;
|
||||||
|
|
||||||
struct cprElfHdr1 {
|
struct cprElfHdr1 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[1];
|
Elf_LE32_Phdr phdr[1];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct cprElfHdr2 {
|
struct cprElfHdr2 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[2];
|
Elf_LE32_Phdr phdr[2];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct cprElfHdr3 {
|
struct cprElfHdr3 {
|
||||||
Elf32_Ehdr ehdr;
|
Elf_LE32_Ehdr ehdr;
|
||||||
Elf32_Phdr phdr[3];
|
Elf_LE32_Phdr phdr[3];
|
||||||
l_info linfo;
|
l_info linfo;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
cprElfHdr3 elfout;
|
cprElfHdr3 elfout;
|
||||||
|
|
||||||
|
struct Elf32_Note {
|
||||||
|
unsigned namesz; // 8
|
||||||
|
unsigned descsz; // 4
|
||||||
|
unsigned type; // 1
|
||||||
|
char text[0x18 - 4*4]; // "OpenBSD"
|
||||||
|
unsigned end; // 0
|
||||||
|
} elfnote;
|
||||||
|
|
||||||
|
unsigned char ei_osabi;
|
||||||
|
char const *osabi_note;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PackBSDI386 : public PackLinuxI386
|
||||||
|
{
|
||||||
|
typedef PackLinuxI386 super;
|
||||||
|
public:
|
||||||
|
PackBSDI386(InputFile *f);
|
||||||
|
virtual int getFormat() const { return UPX_F_BSD_i386; }
|
||||||
|
virtual const char *getName() const { return "*BSD/386"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
|
||||||
|
virtual int buildLoader(const Filter *);
|
||||||
|
};
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+8
-7
@@ -51,9 +51,9 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_pti86.h"
|
#include "stub/i386-linux.elf.interp-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_pti86.h"
|
#include "stub/i386-linux.elf.interp-fold.h"
|
||||||
|
|
||||||
PackLinuxElf32x86interp::PackLinuxElf32x86interp(InputFile *f) :
|
PackLinuxElf32x86interp::PackLinuxElf32x86interp(InputFile *f) :
|
||||||
super(f)
|
super(f)
|
||||||
@@ -148,24 +148,24 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
|||||||
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
||||||
if (opt->o_unix.make_ptinterp) {
|
if (opt->o_unix.make_ptinterp) {
|
||||||
initLoader(linux_i386pti_loader, sizeof(linux_i386pti_loader));
|
initLoader(linux_i386pti_loader, sizeof(linux_i386pti_loader));
|
||||||
linker->addSection("FOLDEXEC", linux_i386pti_fold, sizeof(linux_i386pti_fold));
|
linker->addSection("FOLDEXEC", linux_i386pti_fold, sizeof(linux_i386pti_fold), 0);
|
||||||
|
|
||||||
addLoader("LXPTI000", NULL);
|
addLoader("LXPTI000", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI040", NULL);
|
addLoader("LXPTI040", NULL);
|
||||||
ph.method = M_NRV2B_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI041", NULL);
|
addLoader("LXPTI041", NULL);
|
||||||
ph.method = M_NRV2D_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2D_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI042", NULL);
|
addLoader("LXPTI042", NULL);
|
||||||
ph.method = M_NRV2E_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI043", NULL);
|
addLoader("LXPTI043", NULL);
|
||||||
ph.method = M_CL1B_LE32; addLoader(getDecompressor(), NULL);
|
ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||||
addLoader("LXPTI090", NULL);
|
addLoader("LXPTI090", NULL);
|
||||||
|
|
||||||
addLoader("LXPTI091", NULL);
|
addLoader("LXPTI091", NULL);
|
||||||
@@ -182,6 +182,7 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
|||||||
|
|
||||||
addLoader("LXPTI200", NULL);
|
addLoader("LXPTI200", NULL);
|
||||||
addLoader("FOLDEXEC", NULL);
|
addLoader("FOLDEXEC", NULL);
|
||||||
|
freezeLoader();
|
||||||
upx_byte const *p = getLoader();
|
upx_byte const *p = getLoader();
|
||||||
lsize = getLoaderSize();
|
lsize = getLoaderSize();
|
||||||
updateLoader(fo);
|
updateLoader(fo);
|
||||||
|
|||||||
+3
-3
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 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
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
/* p_lx_sep.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2006 Laszlo Molnar
|
|
||||||
Copyright (C) 2000-2006 John F. Reiser
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
|
||||||
and/or modify them under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation, Inc.,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
|
||||||
|
|
||||||
John F. Reiser
|
|
||||||
<jreiser@users.sourceforge.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#include "file.h"
|
|
||||||
#include "packer.h"
|
|
||||||
#include "p_elf.h"
|
|
||||||
#include "p_unix.h"
|
|
||||||
#include "p_lx_exc.h"
|
|
||||||
#include "p_lx_elf.h"
|
|
||||||
#include "p_lx_sep.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
//#define SCRIPT_SIZE (opt->o_unix.SCRIPT_MAX + sizeof(l_info))
|
|
||||||
#define SCRIPT_SIZE (32 + sizeof(l_info))
|
|
||||||
|
|
||||||
const upx_byte *PackLinuxI386sep::getLoader() const
|
|
||||||
{
|
|
||||||
static char script[SCRIPT_SIZE];
|
|
||||||
|
|
||||||
memset(script, 0, sizeof(script));
|
|
||||||
char const *name = opt->o_unix.script_name;
|
|
||||||
if (0==name) {
|
|
||||||
name = "/usr/local/lib/upxX";
|
|
||||||
}
|
|
||||||
upx_snprintf(script, sizeof(script), "#!%s\n", name);
|
|
||||||
if (M_IS_NRV2B(ph.method)) {
|
|
||||||
script[strlen(script)-2] = 'b';
|
|
||||||
return (upx_byte const *)script;
|
|
||||||
}
|
|
||||||
if (M_IS_NRV2D(ph.method)) {
|
|
||||||
script[strlen(script)-2] = 'd';
|
|
||||||
return (upx_byte const *)script;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PackLinuxI386sep::getLoaderSize() const
|
|
||||||
{
|
|
||||||
if (M_IS_NRV2B(ph.method))
|
|
||||||
return SCRIPT_SIZE;
|
|
||||||
if (M_IS_NRV2D(ph.method))
|
|
||||||
return SCRIPT_SIZE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PackLinuxI386sep::getLoaderPrefixSize() const
|
|
||||||
{
|
|
||||||
return opt->o_unix.SCRIPT_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackLinuxI386sep::patchLoader()
|
|
||||||
{
|
|
||||||
patchLoaderChecksum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
vi:ts=4:et
|
|
||||||
*/
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/* p_lx_sep.h --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
|
||||||
and/or modify them under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation, Inc.,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
|
||||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
|
||||||
|
|
||||||
John F. Reiser
|
|
||||||
<jreiser@users.sourceforge.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_LX_SEP_H //{
|
|
||||||
#define __UPX_P_LX_SEP_H
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// linux/sep386
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
class PackLinuxI386sep : public PackLinuxI386
|
|
||||||
{
|
|
||||||
typedef PackLinuxI386 super;
|
|
||||||
public:
|
|
||||||
PackLinuxI386sep(InputFile *f) : super(f) { }
|
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_SEP_i386; }
|
|
||||||
virtual const char *getName() const { return "linux/sep386"; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual const upx_byte *getLoader() const;
|
|
||||||
virtual int getLoaderSize() const;
|
|
||||||
virtual int getLoaderPrefixSize() const;
|
|
||||||
|
|
||||||
virtual void patchLoader();
|
|
||||||
virtual void updateLoader(OutputFile *) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*} already included */
|
|
||||||
|
|
||||||
/*
|
|
||||||
vi:ts=4:et
|
|
||||||
*/
|
|
||||||
|
|
||||||
+2
-2
@@ -48,9 +48,9 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_lx_sh86.h"
|
#include "stub/i386-linux.elf.shell-entry.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_sh86.h"
|
#include "stub/i386-linux.elf.shell-fold.h"
|
||||||
|
|
||||||
|
|
||||||
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
||||||
|
|||||||
+3
-3
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2000-2004 John F. Reiser
|
Copyright (C) 2000-2006 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
|
||||||
|
|||||||
+46
-20
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 2004 John Reiser
|
Copyright (C) 2004-2006 John Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_mach.h"
|
#include "p_mach.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_mac_ppc32.h"
|
#include "stub/powerpc-darwin.macho-entry.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/fold_machppc32.h"
|
#include "stub/powerpc-darwin.macho-fold.h"
|
||||||
|
|
||||||
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
||||||
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
||||||
@@ -64,17 +64,42 @@ const int *PackMachPPC32::getFilters() const
|
|||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackMachPPC32::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerPpc32;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackMachPPC32::addStubEntrySections(Filter const *)
|
||||||
|
{
|
||||||
|
addLoader("MACOS000", NULL);
|
||||||
|
//addLoader(getDecompressorSections(), NULL);
|
||||||
|
addLoader(
|
||||||
|
( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
|
||||||
|
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
|
||||||
|
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
|
||||||
|
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
|
||||||
|
: NULL), NULL);
|
||||||
|
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PackMachPPC32::defineSymbols(Filter const *)
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
PackMachPPC32::buildMachLoader(
|
PackMachPPC32::buildMachLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
upx_byte const *const fold,
|
upx_byte const *const fold,
|
||||||
unsigned const szfold,
|
unsigned const szfold,
|
||||||
Filter const */*ft*/
|
Filter const *ft
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int eof_empty = -1;
|
initLoader(proto, szproto);
|
||||||
initLoader(&eof_empty, 4096, 0, 0);
|
|
||||||
|
|
||||||
struct b_info h; memset(&h, 0, sizeof(h));
|
struct b_info h; memset(&h, 0, sizeof(h));
|
||||||
unsigned fold_hdrlen = 0;
|
unsigned fold_hdrlen = 0;
|
||||||
@@ -88,7 +113,7 @@ PackMachPPC32::buildMachLoader(
|
|||||||
|
|
||||||
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
||||||
if (0 < szfold) {
|
if (0 < szfold) {
|
||||||
unsigned sz_cpr;
|
unsigned sz_cpr = 0;
|
||||||
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr,
|
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr,
|
||||||
NULL, ph.method, 10, NULL, NULL );
|
NULL, ph.method, 10, NULL, NULL );
|
||||||
h.sz_cpr = sz_cpr;
|
h.sz_cpr = sz_cpr;
|
||||||
@@ -98,16 +123,17 @@ PackMachPPC32::buildMachLoader(
|
|||||||
memcpy(cprLoader, &h, sizeof(h));
|
memcpy(cprLoader, &h, sizeof(h));
|
||||||
|
|
||||||
// This adds the definition to the "library", to be used later.
|
// This adds the definition to the "library", to be used later.
|
||||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr);
|
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr, 0);
|
||||||
delete [] cprLoader;
|
delete [] cprLoader;
|
||||||
|
|
||||||
int const GAP = 128; // must match stub/l_mac_ppc.S
|
int const GAP = 128; // must match stub/l_mac_ppc.S
|
||||||
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64;
|
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64;
|
||||||
|
|
||||||
linker->addSection("MACOS000", proto, szproto);
|
addStubEntrySections(ft);
|
||||||
|
|
||||||
addLoader("MACOS000", NULL);
|
freezeLoader();
|
||||||
addLoader("FOLDEXEC", NULL);
|
defineSymbols(ft);
|
||||||
|
linker->relocate();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +150,7 @@ void PackMachPPC32::updateLoader(OutputFile *) {}
|
|||||||
void
|
void
|
||||||
PackMachPPC32::patchLoaderChecksum()
|
PackMachPPC32::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = &linfo;
|
l_info *const lp = &linfo;
|
||||||
// checksum for loader; also some PackHeader info
|
// checksum for loader; also some PackHeader info
|
||||||
lp->l_checksum = 0;
|
lp->l_checksum = 0;
|
||||||
@@ -225,13 +251,13 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
unsigned k;
|
unsigned k;
|
||||||
|
|
||||||
// count passes, set ptload vars
|
// count passes, set ptload vars
|
||||||
ui_total_passes = 0;
|
uip->ui_total_passes = 0;
|
||||||
for (k = 0; k < n_segment; ++k) {
|
for (k = 0; k < n_segment; ++k) {
|
||||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||||
&& 0!=msegcmd[k].filesize ) {
|
&& 0!=msegcmd[k].filesize ) {
|
||||||
ui_total_passes++;
|
uip->ui_total_passes++;
|
||||||
if (find_SEGMENT_gap(k)) {
|
if (find_SEGMENT_gap(k)) {
|
||||||
ui_total_passes++;
|
uip->ui_total_passes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,9 +266,9 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
unsigned total_in = 0;
|
unsigned total_in = 0;
|
||||||
unsigned total_out = 0;
|
unsigned total_out = 0;
|
||||||
|
|
||||||
unsigned hdr_ulen = mhdri.sizeofcmds;
|
unsigned hdr_u_len = mhdri.sizeofcmds;
|
||||||
|
|
||||||
ui_pass = 0;
|
uip->ui_pass = 0;
|
||||||
ft.addvalue = 0;
|
ft.addvalue = 0;
|
||||||
|
|
||||||
int nx = 0;
|
int nx = 0;
|
||||||
@@ -258,8 +284,8 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
}
|
}
|
||||||
packExtent(x, total_in, total_out,
|
packExtent(x, total_in, total_out,
|
||||||
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||||
? &ft : 0 ), fo, hdr_ulen );
|
? &ft : 0 ), fo, hdr_u_len );
|
||||||
hdr_ulen = 0;
|
hdr_u_len = 0;
|
||||||
++nx;
|
++nx;
|
||||||
}
|
}
|
||||||
for (k = 0; k < n_segment; ++k) {
|
for (k = 0; k < n_segment; ++k) {
|
||||||
|
|||||||
+5
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -181,6 +181,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void patchLoaderChecksum();
|
virtual void patchLoaderChecksum();
|
||||||
virtual void updateLoader(OutputFile *);
|
virtual void updateLoader(OutputFile *);
|
||||||
@@ -190,6 +191,8 @@ protected:
|
|||||||
upx_byte const *const fold,
|
upx_byte const *const fold,
|
||||||
unsigned const szfold,
|
unsigned const szfold,
|
||||||
Filter const *ft );
|
Filter const *ft );
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
unsigned n_segment;
|
unsigned n_segment;
|
||||||
unsigned sz_segment;
|
unsigned sz_segment;
|
||||||
|
|||||||
+399
-160
@@ -35,31 +35,31 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_ps1.h"
|
#include "p_ps1.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_ps1b.h"
|
#include "stub/mipsel.r3000-ps1.h"
|
||||||
static const
|
|
||||||
#include "stub/l_ps1c.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MIPS_HI(a) ((a) >> 16)
|
|
||||||
#define MIPS_LO(a) ((a) & 0xffff)
|
|
||||||
#define MIPS_JP(a) ((0x08 << 24) | (((a) & 0x0fffffff) >> 2))
|
|
||||||
#define TIL_ALIGNED(a,b) (((b) - ((a) & ((b) - 1))) & (b) - 1)
|
|
||||||
|
|
||||||
#define CD_SEC 2048
|
#define CD_SEC 2048
|
||||||
#define PS_HDR_SIZE CD_SEC
|
#define PS_HDR_SIZE CD_SEC
|
||||||
#define PS_RAM_SIZE 0x200000
|
#define PS_RAM_SIZE ram_size
|
||||||
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
||||||
#define PS_MAX_SIZE 0x1e8000
|
#define PS_MAX_SIZE ((PS_RAM_SIZE*95) / 100)
|
||||||
|
#define PS_STACK_SIZE (PS_RAM_SIZE / 256)
|
||||||
|
|
||||||
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
||||||
#define HD_CODE_OFS (sizeof(ps1_exe_t))
|
#define HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh)
|
||||||
|
|
||||||
#define K0_BS (0x80000000)
|
#define K0_BS (0x80000000)
|
||||||
#define K1_BS (0xa0000000)
|
#define K1_BS (0xa0000000)
|
||||||
#define FIX_PSVR (K1_BS - (ih.epc & K0_BS)) + (PS_HDR_SIZE - HD_CODE_OFS)
|
#define EXE_BS (ih.epc & K0_BS)
|
||||||
|
#define FIX_PSVR (K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS)
|
||||||
|
|
||||||
|
// lui / addiu
|
||||||
|
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||||
|
#define MIPS_LO(a) ((a) & 0xffff)
|
||||||
|
#define MIPS_PC16(a) ((a) >> 2)
|
||||||
|
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// ps1 exe looks like this:
|
// ps1 exe looks like this:
|
||||||
@@ -78,21 +78,23 @@ static const
|
|||||||
PackPs1::PackPs1(InputFile *f) :
|
PackPs1::PackPs1(InputFile *f) :
|
||||||
super(f),
|
super(f),
|
||||||
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
|
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
|
||||||
overlap(0), sa_cnt(0)
|
buildPart2(0), foundBss(0), sa_cnt(0), overlap(0), sz_lunc(0), sz_lcpr(0),
|
||||||
|
pad_code(0), bss_start(0), bss_end(0)
|
||||||
{
|
{
|
||||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188);
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136);
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44);
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5);
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
||||||
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
|
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
|
||||||
#if 1 || defined(WITH_NRV)
|
#if 0 // 1 || defined(WITH_NRV)
|
||||||
COMPILE_TIME_ASSERT(sizeof(nrv_boot_loader) == 3935);
|
COMPILE_TIME_ASSERT(sizeof(nrv_loader) == 14812);
|
||||||
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0ac25782);
|
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0);
|
||||||
COMPILE_TIME_ASSERT(sizeof(nrv_con_loader) == 2829);
|
|
||||||
COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0x923b55c4);
|
|
||||||
#endif
|
#endif
|
||||||
fdata_size = file_size - PS_HDR_SIZE;
|
fdata_size = file_size - PS_HDR_SIZE;
|
||||||
|
ram_size = !opt->ps1_exe.do_8mb ? 0x200000 : 0x800000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackPs1::getCompressionMethods(int method, int level) const
|
const int *PackPs1::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
if (is32Bit)
|
if (is32Bit)
|
||||||
@@ -101,12 +103,40 @@ const int *PackPs1::getCompressionMethods(int method, int level) const
|
|||||||
return Packer::getDefaultCompressionMethods_8(method, level);
|
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackPs1::getFilters() const
|
const int *PackPs1::getFilters() const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker* PackPs1::newLinker() const
|
||||||
|
{
|
||||||
|
class ElfLinkerMipsLE : public ElfLinker
|
||||||
|
{
|
||||||
|
typedef ElfLinker super;
|
||||||
|
|
||||||
|
virtual void relocate1(const Relocation *rel, upx_byte *location,
|
||||||
|
unsigned value, const char *type)
|
||||||
|
{
|
||||||
|
if (strcmp(type, "R_MIPS_HI16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + MIPS_HI(value));
|
||||||
|
else if (strcmp(type, "R_MIPS_LO16") == 0)
|
||||||
|
set_le16(location, get_le16(location) + MIPS_LO(value));
|
||||||
|
else if (strcmp(type, "R_MIPS_PC16") == 0)
|
||||||
|
{
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
set_le16(location, get_le16(location) + MIPS_PC16(value));
|
||||||
|
}
|
||||||
|
else if (strcmp(type, "R_MIPS_26") == 0)
|
||||||
|
set_le32(location, get_le32(location) + MIPS_PC26(value));
|
||||||
|
else if (strcmp(type, "R_MIPS_32") == 0)
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
else
|
||||||
|
super::relocate1(rel, location, value, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new ElfLinkerMipsLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
@@ -126,6 +156,78 @@ int PackPs1::readFileHeader()
|
|||||||
return UPX_F_PS1_EXE;
|
return UPX_F_PS1_EXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PackPs1::readBkupHeader()
|
||||||
|
{
|
||||||
|
fi->seek(sizeof(ps1_exe_t)+8, SEEK_SET);
|
||||||
|
fi->readx(&bh, sizeof(bh));
|
||||||
|
|
||||||
|
if (bh.ih_csum != upx_adler32(&bh, SZ_IH_BKUP))
|
||||||
|
{
|
||||||
|
unsigned char buf[sizeof(bh)];
|
||||||
|
fi->seek(sizeof(ps1_exe_t), SEEK_SET);
|
||||||
|
fi->readx(buf, sizeof(bh));
|
||||||
|
if (!getBkupHeader(buf, (unsigned char *)&bh))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_BH_BKUP(p, l) {(p)->id = '1'; (p)->len = l;}
|
||||||
|
#define ADLER16(a) ((a) >> 16 ^ ((a) & 0xffff))
|
||||||
|
|
||||||
|
void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len)
|
||||||
|
{
|
||||||
|
unsigned sz_cbh;
|
||||||
|
|
||||||
|
if (src && dst)
|
||||||
|
{
|
||||||
|
unsigned char *cpr_bh = new unsigned char[MemBuffer::getSizeForCompression(SZ_IH_BKUP)];
|
||||||
|
|
||||||
|
memset(cpr_bh, 0, sizeof(bh));
|
||||||
|
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
|
||||||
|
|
||||||
|
int r = upx_compress(src, SZ_IH_BKUP,
|
||||||
|
&p->ih_bkup, &sz_cbh, NULL, M_NRV2E_8, 10, NULL, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
|
||||||
|
throwInternalError("header compression failed");
|
||||||
|
INIT_BH_BKUP(p, sz_cbh);
|
||||||
|
*len = ALIGN_UP(sz_cbh + sizeof(ps1_exe_chb_t) - 1, 4);
|
||||||
|
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
|
||||||
|
memcpy(dst, cpr_bh, SZ_IH_BKUP);
|
||||||
|
delete [] cpr_bh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throwInternalError("header compression failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADLER16_HI(a, b) ((((a) & 0xffff) ^ (b)) << 16)
|
||||||
|
#define ADLER16_LO(a, b) (((a) >> 16) ^ (b))
|
||||||
|
#define RE_ADLER16(a, b) (ADLER16_HI(a,b) | ADLER16_LO(a,b))
|
||||||
|
|
||||||
|
bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst)
|
||||||
|
{
|
||||||
|
ps1_exe_chb_t *src = (ps1_exe_chb_t*)p;
|
||||||
|
|
||||||
|
if (src && (src->id == '1' && src->len < SZ_IH_BKUP) && dst)
|
||||||
|
{
|
||||||
|
unsigned char *unc_bh = new unsigned char[MemBuffer::getSizeForUncompression(SZ_IH_BKUP)];
|
||||||
|
|
||||||
|
unsigned sz_bh = SZ_IH_BKUP;
|
||||||
|
int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len,
|
||||||
|
unc_bh, &sz_bh, M_NRV2E_8, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_bh != SZ_IH_BKUP)
|
||||||
|
throwInternalError("header decompression failed");
|
||||||
|
unsigned ad = upx_adler32(unc_bh, SZ_IH_BKUP);
|
||||||
|
unsigned ch = src->ih_csum;
|
||||||
|
if (ad != RE_ADLER16(ad,ch))
|
||||||
|
throwInternalError("backup header damaged");
|
||||||
|
memcpy(dst, unc_bh, SZ_IH_BKUP);
|
||||||
|
delete [] unc_bh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PackPs1::checkFileHeader()
|
bool PackPs1::checkFileHeader()
|
||||||
{
|
{
|
||||||
@@ -148,57 +250,24 @@ bool PackPs1::checkFileHeader()
|
|||||||
infoWarning("unsupported header field entry");
|
infoWarning("unsupported header field entry");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!opt->force && ih.is_ptr == 0)
|
if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
|
||||||
{
|
{
|
||||||
infoWarning("stack pointer field empty");
|
if (!opt->force)
|
||||||
return false;
|
return false;
|
||||||
|
else
|
||||||
|
infoWarning("%s: stack pointer offset low", fi->getName());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// patch util
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
void PackPs1::patch_mips_le(void *b, int blen, const void *old, unsigned new_)
|
|
||||||
{
|
|
||||||
size_t patch_len = strlen((const char*)old);
|
|
||||||
|
|
||||||
if (patch_len == 2)
|
|
||||||
{
|
|
||||||
unsigned char w[2];
|
|
||||||
|
|
||||||
set_le16(w, get_be16(old));
|
|
||||||
patch_le16(b, blen, w, MIPS_LO(new_));
|
|
||||||
}
|
|
||||||
else if (patch_len == 4)
|
|
||||||
{
|
|
||||||
unsigned char w[4];
|
|
||||||
|
|
||||||
set_le32(w, get_be32(old));
|
|
||||||
int boff = find(b, blen, w, 4);
|
|
||||||
|
|
||||||
if (boff == -1)
|
|
||||||
{
|
|
||||||
patch_le16(b, blen, &w[0], MIPS_LO(new_));
|
|
||||||
patch_le16(b, blen, &w[2], MIPS_HI(new_));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
patch_le32((unsigned char *)b + boff, (blen-boff), &w, new_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throwInternalError("bad marker length");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackPs1::canPack()
|
bool PackPs1::canPack()
|
||||||
{
|
{
|
||||||
unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS];
|
unsigned char buf[PS_HDR_SIZE - sizeof(ps1_exe_t)];
|
||||||
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
@@ -221,7 +290,7 @@ bool PackPs1::canPack()
|
|||||||
throwCantPack("unsupported header flags (try --force)");
|
throwCantPack("unsupported header flags (try --force)");
|
||||||
if (!opt->force && file_size < PS_MIN_SIZE)
|
if (!opt->force && file_size < PS_MIN_SIZE)
|
||||||
throwCantPack("file is too small (try --force)");
|
throwCantPack("file is too small (try --force)");
|
||||||
if (!opt->force && file_size > PS_MAX_SIZE)
|
if (!opt->force && file_size > (off_t) PS_MAX_SIZE)
|
||||||
throwCantPack("file is too big (try --force)");
|
throwCantPack("file is too big (try --force)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -233,44 +302,184 @@ bool PackPs1::canPack()
|
|||||||
|
|
||||||
int PackPs1::buildLoader(const Filter *)
|
int PackPs1::buildLoader(const Filter *)
|
||||||
{
|
{
|
||||||
if (isCon)
|
const char *method = NULL;
|
||||||
initLoader(nrv_con_loader,sizeof(nrv_con_loader));
|
|
||||||
else
|
|
||||||
initLoader(nrv_boot_loader,sizeof(nrv_boot_loader));
|
|
||||||
|
|
||||||
addLoader("PS1START",
|
|
||||||
isCon ? ph.c_len & 3 ? "PS1PADCD" : "" : "PS1ENTRY",
|
|
||||||
ih.tx_ptr & 0xffff ? "PS1CONHL" : "PS1CONHI",
|
|
||||||
isCon ? "PS1ENTRY" : "",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (ph.method == M_NRV2B_8)
|
if (ph.method == M_NRV2B_8)
|
||||||
addLoader("PS1N2B08", NULL);
|
method = isCon ? "nrv2b.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2b.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2D_8)
|
else if (ph.method == M_NRV2D_8)
|
||||||
addLoader("PS1N2D08", NULL);
|
method = isCon ? "nrv2d.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2d.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2E_8)
|
else if (ph.method == M_NRV2E_8)
|
||||||
addLoader("PS1N2E08", NULL);
|
method = isCon ? "nrv2e.small,8bit.sub,nrv.done" :
|
||||||
|
"nrv2e.8bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2B_LE32)
|
else if (ph.method == M_NRV2B_LE32)
|
||||||
addLoader("PS1N2B32", NULL);
|
method = isCon ? "nrv2b.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2b.32bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2D_LE32)
|
else if (ph.method == M_NRV2D_LE32)
|
||||||
addLoader("PS1N2D32", NULL);
|
method = isCon ? "nrv2d.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2d.32bit,nrv.done";
|
||||||
else if (ph.method == M_NRV2E_LE32)
|
else if (ph.method == M_NRV2E_LE32)
|
||||||
addLoader("PS1N2E32", NULL);
|
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
|
||||||
|
"nrv2e.32bit,nrv.done";
|
||||||
|
else if (ph.method == M_LZMA)
|
||||||
|
method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
|
||||||
else
|
else
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
|
||||||
if (sa_cnt)
|
unsigned sa_tmp = sa_cnt;
|
||||||
addLoader(sa_cnt > (0x10000 << 2) ? "PS1MSETB" : "PS1MSETS",
|
if (ph.overlap_overhead > sa_cnt)
|
||||||
ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA",
|
{
|
||||||
NULL);
|
if (!opt->force)
|
||||||
|
{
|
||||||
|
infoWarning("not in-place decompressible");
|
||||||
|
throwCantPack("packed data overlap (try --force)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp),4);
|
||||||
|
}
|
||||||
|
|
||||||
addLoader("PS1EXITC", "IDENTSTR", "PS1PAHDR",
|
foundBss = findBssSection();
|
||||||
isCon ? "PS1SREGS" : "",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
if (ph.method == M_LZMA && !buildPart2)
|
||||||
|
{
|
||||||
|
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||||
|
addLoader("decompressor.start",
|
||||||
|
isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
|
||||||
|
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
|
||||||
|
!foundBss ? "con.exit" : "bss.exit", NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ph.method == M_LZMA && buildPart2)
|
||||||
|
{
|
||||||
|
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
|
||||||
|
unsigned char *cprLoader = new unsigned char[sz_lcpr];
|
||||||
|
int r = upx_compress(getLoader(), sz_lunc, cprLoader, &sz_lcpr,
|
||||||
|
NULL, M_NRV2B_8, 10, NULL, NULL );
|
||||||
|
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
|
||||||
|
throwInternalError("loader compression failed");
|
||||||
|
initLoader(nrv_loader, sizeof(nrv_loader),
|
||||||
|
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||||
|
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
|
||||||
|
delete [] cprLoader;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||||
|
|
||||||
|
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4);
|
||||||
|
linker->addSection("pad.code", &pad_code, pad_code, 0);
|
||||||
|
|
||||||
|
if (isCon)
|
||||||
|
{
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
addLoader(!foundBss ? "con.start" : "bss.con.start",
|
||||||
|
method,
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"con.entry", "pad.code", "lzma.exec", NULL);
|
||||||
|
else
|
||||||
|
addLoader(!foundBss ? "con.start" : "bss.con.start", "con.mcpy",
|
||||||
|
ph.c_len & 3 ? "con.padcd" : "",
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"con.entry", method,
|
||||||
|
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||||
|
!foundBss ? "con.exit" : "bss.exit",
|
||||||
|
"pad.code", NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
|
||||||
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
|
"lzma.exec", NULL);
|
||||||
|
else
|
||||||
|
addLoader("cdb.start", "pad.code", "cdb.entry",
|
||||||
|
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
|
||||||
|
method,
|
||||||
|
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||||
|
!foundBss ? "cdb.exit" : "bss.exit",
|
||||||
|
"pad.code", NULL);
|
||||||
|
}
|
||||||
|
addLoader("UPX1HEAD", "IDENTSTR", NULL);
|
||||||
|
}
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define OPTYPE(x) (((x) >> 13) & 0x7)
|
||||||
|
#define OPCODE(x) (((x) >> 10) & 0x7)
|
||||||
|
#define REG1(x) (((x) >> 5) & 0x1f)
|
||||||
|
#define REG2(x) ((x) & 0x1f)
|
||||||
|
|
||||||
|
#define MIPS_IMM(a,b) (((a) - (((b) & 0x8000) >> 15) << 16) | (b))
|
||||||
|
|
||||||
|
// Type
|
||||||
|
#define REGIMM 1
|
||||||
|
#define STORE 5
|
||||||
|
// Op
|
||||||
|
#define LUI 7
|
||||||
|
#define ADDIU 1
|
||||||
|
#define SW 3
|
||||||
|
|
||||||
|
#define IS_LUI(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == LUI))
|
||||||
|
#define IS_ADDIU(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == ADDIU))
|
||||||
|
#define IS_SW_ZERO(a) ((OPTYPE(a) == STORE && OPCODE(a) == SW) && REG2(a) == 0)
|
||||||
|
|
||||||
|
#define BSS_CHK_LIMIT (18)
|
||||||
|
|
||||||
|
bool PackPs1::findBssSection()
|
||||||
|
{
|
||||||
|
unsigned char reg;
|
||||||
|
LE32 *p1 = (LE32 *)(ibuf + (ih.epc - ih.tx_ptr));
|
||||||
|
|
||||||
|
if ((ih.epc - ih.tx_ptr + (BSS_CHK_LIMIT * 4)) > fdata_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check 18 opcodes for sw zero,0(x)
|
||||||
|
for (signed i = BSS_CHK_LIMIT; i >= 0; i--)
|
||||||
|
{
|
||||||
|
unsigned short op = p1[i] >> 16;
|
||||||
|
if (IS_SW_ZERO(op))
|
||||||
|
{
|
||||||
|
// found! get reg (x) for bss_start
|
||||||
|
reg = REG1(op);
|
||||||
|
for (; i >= 0; i--)
|
||||||
|
{
|
||||||
|
bss_nfo *p = (bss_nfo *)&p1[i];
|
||||||
|
unsigned short op1 = p->op1, op2 = p->op2;
|
||||||
|
|
||||||
|
// check for la (x),bss_start
|
||||||
|
if ((IS_LUI(op1) && REG2(op1) == reg) &&
|
||||||
|
(IS_ADDIU(op2) && REG1(op2) == reg))
|
||||||
|
{
|
||||||
|
op1 = p->op3, op2 = p->op4;
|
||||||
|
|
||||||
|
// check for la (y),bss_end
|
||||||
|
if (IS_LUI(op1) && IS_ADDIU(op2))
|
||||||
|
{
|
||||||
|
// bss section info found!
|
||||||
|
bss_start = MIPS_IMM(p->hi1, p->lo1);
|
||||||
|
bss_end = MIPS_IMM(p->hi2, p->lo2);
|
||||||
|
|
||||||
|
if (0 < ALIGN_DOWN(bss_end - bss_start, 4) )
|
||||||
|
{
|
||||||
|
unsigned wkmem_sz = (ph.method == M_LZMA) ? 32768 : 800;
|
||||||
|
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
|
||||||
|
if (bss_end > (end_offs + wkmem_sz))
|
||||||
|
return (isCon || (!isCon && (ph.method == M_LZMA)));
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -301,29 +510,47 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
|
|
||||||
// compress (max_match = 65535)
|
// compress (max_match = 65535)
|
||||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = 65535;
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, sa_cnt, 0, NULL, &cconf);
|
||||||
|
|
||||||
if (ph.overlap_overhead > sa_cnt)
|
if (overlap)
|
||||||
{
|
{
|
||||||
if (!opt->force)
|
|
||||||
{
|
|
||||||
infoWarning("not in-place decompressible");
|
|
||||||
throwCantPack("packed data overlap (try --force)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
overlap = ALIGN_UP((ph.overlap_overhead-sa_cnt),4);
|
|
||||||
opt->info_mode += !opt->info_mode ? 1 : 0;
|
opt->info_mode += !opt->info_mode ? 1 : 0;
|
||||||
infoWarning("%s: memory overlap %d bytes",fi->getName(),overlap);
|
infoWarning("overlap - relocating load address (+%d bytes)", overlap);
|
||||||
|
sa_cnt += overlap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (bss_start && bss_end && !foundBss)
|
||||||
|
infoWarning("%s: .bss section too small - use stack", fi->getName());
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned lzma_init = 0;
|
||||||
|
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
{
|
||||||
|
sz_lunc = getLoaderSize();
|
||||||
|
|
||||||
|
lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init"));
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
linker->defineSymbol("entry", ih.epc);
|
||||||
|
linker->defineSymbol("SC",
|
||||||
|
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
|
||||||
|
linker->relocate();
|
||||||
|
|
||||||
|
buildPart2 = true;
|
||||||
|
buildLoader(&ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&oh, &ih, sizeof(ih));
|
memcpy(&oh, &ih, sizeof(ih));
|
||||||
memcpy(&oh.ih_bkup, &ih.epc, SZ_IH_BKUP);
|
|
||||||
oh.ih_csum = upx_adler32(&ih.epc, SZ_IH_BKUP);
|
|
||||||
|
|
||||||
if (ih.is_ptr == 0)
|
unsigned sz_cbh;
|
||||||
oh.is_ptr = PS_RAM_SIZE-0x10;
|
putBkupHeader((const unsigned char *)&ih.epc, (unsigned char *)&bh, &sz_cbh);
|
||||||
|
|
||||||
|
if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))
|
||||||
|
oh.is_ptr = (EXE_BS | (PS_RAM_SIZE - 16));
|
||||||
|
|
||||||
if (ih.da_ptr != 0 || ih.da_len != 0 ||
|
if (ih.da_ptr != 0 || ih.da_len != 0 ||
|
||||||
ih.bs_ptr != 0 || ih.bs_len != 0)
|
ih.bs_ptr != 0 || ih.bs_len != 0)
|
||||||
@@ -334,44 +561,45 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
memcpy(loader, getLoader(), lsize);
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
|
||||||
patchPackHeader(loader,lsize);
|
|
||||||
|
|
||||||
unsigned pad = 0;
|
|
||||||
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
|
unsigned filelen = ALIGN_UP(ih.tx_len, 4);
|
||||||
unsigned pad_code = TIL_ALIGNED(ph.c_len, 4);
|
|
||||||
|
|
||||||
const unsigned decomp_data_start = ih.tx_ptr;
|
const unsigned decomp_data_start = ih.tx_ptr;
|
||||||
const unsigned comp_data_start = ((decomp_data_start + filelen + overlap) - ph.c_len);
|
const unsigned comp_data_start = (decomp_data_start + filelen + overlap) - ph.c_len;
|
||||||
|
|
||||||
const int h_len = lsize - getLoaderSectionStart("IDENTSTR");
|
const int h_len = lsize - getLoaderSectionStart("UPX1HEAD");
|
||||||
const int c_len = lsize - h_len;
|
|
||||||
int d_len = 0;
|
int d_len = 0;
|
||||||
int e_len = 0;
|
int e_len = 0;
|
||||||
|
|
||||||
if (isCon)
|
if (isCon)
|
||||||
{
|
{
|
||||||
e_len = lsize - h_len;
|
e_len = lsize - h_len;
|
||||||
d_len = e_len - getLoaderSectionStart("PS1ENTRY");
|
d_len = e_len - getLoaderSectionStart("con.entry");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_len = (lsize - h_len) - getLoaderSectionStart("PS1ENTRY");
|
d_len = (lsize - h_len) - getLoaderSectionStart((ph.method == M_LZMA) ? "cdb.entry.lzma" : "cdb.entry");
|
||||||
e_len = (lsize - d_len) - h_len;
|
e_len = (lsize - d_len) - h_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
patch_mips_le(loader,c_len,"JPEP",MIPS_JP(ih.epc));
|
linker->defineSymbol("entry", ih.epc);
|
||||||
if (sa_cnt)
|
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
|
||||||
patch_mips_le(loader,c_len,"SC",
|
sa_cnt >> 5 : sa_cnt >> 2));
|
||||||
MIPS_LO(sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2));
|
linker->defineSymbol("DECO", decomp_data_start);
|
||||||
if (ih.tx_ptr & 0xffff)
|
linker->defineSymbol("ldr_sz", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
|
||||||
patch_mips_le(loader,c_len,"DECO",decomp_data_start);
|
|
||||||
else
|
|
||||||
patch_mips_le(loader,c_len,"DE",MIPS_HI(decomp_data_start));
|
|
||||||
|
|
||||||
const unsigned entry = comp_data_start - e_len - pad_code;
|
if (foundBss)
|
||||||
oh.tx_ptr = entry;
|
if (ph.method == M_LZMA)
|
||||||
oh.tx_len = ph.c_len + e_len + pad_code;
|
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
|
||||||
oh.epc = comp_data_start - e_len - pad_code;
|
- (sz_lunc + 16));
|
||||||
|
else
|
||||||
|
linker->defineSymbol("wrkmem", bss_end - 16 - (d_len - pad_code));
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned entry = comp_data_start - e_len;
|
||||||
|
oh.epc = oh.tx_ptr = entry;
|
||||||
|
oh.tx_len = ph.c_len + e_len;
|
||||||
|
|
||||||
|
unsigned pad = 0;
|
||||||
|
|
||||||
if (!opt->ps1_exe.no_align)
|
if (!opt->ps1_exe.no_align)
|
||||||
{
|
{
|
||||||
@@ -384,43 +612,50 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
ibuf.clear(0,fdata_size);
|
ibuf.clear(0,fdata_size);
|
||||||
upx_bytep paddata = ibuf;
|
upx_bytep paddata = ibuf;
|
||||||
|
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
{
|
||||||
|
linker->defineSymbol("lzma_init_off", lzma_init);
|
||||||
|
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (isCon)
|
||||||
|
linker->defineSymbol("gb_e", linker->getSymbolOffset(is32Bit ? "gb32_e" : "gb8_e"));
|
||||||
|
|
||||||
if (isCon)
|
if (isCon)
|
||||||
{
|
{
|
||||||
if (pad_code)
|
linker->defineSymbol("PAD", pad_code);
|
||||||
patch_mips_le(loader, c_len, "PC", pad_code);
|
if (ph.method == M_LZMA)
|
||||||
patch_mips_le(loader, c_len, "DCRT", entry + (e_len - d_len));
|
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
|
||||||
patch_mips_le(loader, c_len, "LS",
|
else
|
||||||
d_len + get_le32(&loader[getLoaderSectionStart("PS1SREGS")]));
|
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
|
||||||
|
|
||||||
// ps1_exe_t structure 188 bytes
|
|
||||||
fo->write(&oh,sizeof(oh));
|
|
||||||
// id & upx header
|
|
||||||
fo->write(loader + e_len,h_len);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
patch_mips_le(loader, c_len, "CPDO", comp_data_start);
|
linker->defineSymbol("PSVR", FIX_PSVR);
|
||||||
patch_mips_le(loader, e_len, "PSVR", FIX_PSVR);
|
linker->defineSymbol("CPDO", comp_data_start);
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
// ps1_exe_t structure 188 bytes
|
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
|
||||||
fo->write(&oh,sizeof(oh));
|
- getLoaderSectionStart("cdb.entry.lzma"));
|
||||||
// decompressor
|
|
||||||
fo->write(loader + e_len, d_len);
|
|
||||||
// id & upx header
|
|
||||||
fo->write(loader + e_len + d_len, h_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// header size is 2048 bytes
|
linker->relocate();
|
||||||
fo->write(paddata, PS_HDR_SIZE - fo->getBytesWritten());
|
memcpy(loader, getLoader(), lsize);
|
||||||
// sector alignment
|
patchPackHeader(loader, lsize);
|
||||||
if (pad)
|
|
||||||
fo->write(paddata, pad);
|
if (!isCon && ph.method == M_LZMA && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
|
||||||
|
throwInternalError("lzma --boot-only loader > 2048");
|
||||||
|
|
||||||
|
// ps1_exe_t structure
|
||||||
|
fo->write(&oh, sizeof(oh));
|
||||||
|
fo->write(&bh, sz_cbh);
|
||||||
|
// decompressor
|
||||||
|
fo->write(loader + e_len, isCon ? h_len : (d_len + h_len));
|
||||||
|
|
||||||
|
// header size is 2048 bytes + sector alignment
|
||||||
|
fo->write(paddata, (pad + PS_HDR_SIZE) - fo->getBytesWritten());
|
||||||
// entry
|
// entry
|
||||||
fo->write(loader, e_len);
|
fo->write(loader, e_len);
|
||||||
// code must be aligned to 4!
|
// compressed body
|
||||||
if (pad_code)
|
|
||||||
fo->write(paddata, pad_code);
|
|
||||||
// compressed binary / data
|
|
||||||
fo->write(obuf, ph.c_len);
|
fo->write(obuf, ph.c_len);
|
||||||
|
|
||||||
verifyOverlappingDecompression();
|
verifyOverlappingDecompression();
|
||||||
@@ -430,13 +665,21 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len);
|
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len);
|
||||||
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
||||||
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len);
|
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len - pad_code);
|
||||||
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
printf("%-13s: header comp : %8ld bytes\n", getName(), (long) sz_cbh);
|
||||||
|
printf("%-13s: overlap : %8ld bytes\n", getName(), (long) overlap);
|
||||||
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
||||||
|
printf("%-13s: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
||||||
|
printf("%-13s: bbs start : %08X bytes\n", getName(), (unsigned int) bss_start);
|
||||||
|
printf("%-13s: bbs end : %08X bytes\n", getName(), (unsigned int) bss_end);
|
||||||
printf("%-13s: eof in mem IF : %08X bytes\n", getName(), (unsigned int) ih.tx_ptr + ih.tx_len);
|
printf("%-13s: eof in mem IF : %08X bytes\n", getName(), (unsigned int) ih.tx_ptr + ih.tx_len);
|
||||||
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
|
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
|
||||||
|
unsigned char i = 0;
|
||||||
|
if (isCon) { if (foundBss) i = 1; }
|
||||||
|
else { i = 2; if (ph.method == M_LZMA) { if (!foundBss) i = 3; else i = 4; } }
|
||||||
|
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
|
||||||
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
||||||
printf("%-13s: compressor : %s\n", getName(), method_name);
|
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,11 +692,10 @@ int PackPs1::canUnpack()
|
|||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (!readPackHeader(1024))
|
if (!readPackHeader(CD_SEC))
|
||||||
return false;
|
return false;
|
||||||
// check header as set by packer
|
// check header as set by packer
|
||||||
if (ih.ih_csum != upx_adler32(&ih.ih_bkup, SZ_IH_BKUP) &&
|
if (!readBkupHeader() || ph.c_len >= fdata_size)
|
||||||
(ph.c_len >= fdata_size))
|
|
||||||
throwCantUnpack("header damaged");
|
throwCantUnpack("header damaged");
|
||||||
// generic check
|
// generic check
|
||||||
if (!checkFileHeader())
|
if (!checkFileHeader())
|
||||||
@@ -470,7 +712,7 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
{
|
{
|
||||||
// restore orig exec hdr
|
// restore orig exec hdr
|
||||||
memcpy(&oh, &ih, sizeof(ih));
|
memcpy(&oh, &ih, sizeof(ih));
|
||||||
memcpy(&oh.epc, &ih.ih_bkup, SZ_IH_BKUP);
|
memcpy(&oh.epc, &bh, SZ_IH_BKUP);
|
||||||
|
|
||||||
// check for removed sector alignment
|
// check for removed sector alignment
|
||||||
assert(oh.tx_len >= ph.u_len);
|
assert(oh.tx_len >= ph.u_len);
|
||||||
@@ -482,9 +724,6 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
||||||
fi->readx(ibuf, fdata_size);
|
fi->readx(ibuf, fdata_size);
|
||||||
|
|
||||||
// clear backup and checksum of header
|
|
||||||
memset(&oh.ih_bkup, 0, SZ_IH_BKUP+4);
|
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
decompress(ibuf + (fdata_size - ph.c_len), obuf);
|
decompress(ibuf + (fdata_size - ph.c_len), obuf);
|
||||||
|
|
||||||
@@ -495,14 +734,14 @@ void PackPs1::unpack(OutputFile *fo)
|
|||||||
fo->write(&oh, sizeof(oh));
|
fo->write(&oh, sizeof(oh));
|
||||||
// align the ps exe header (mode 2 sector data size)
|
// align the ps exe header (mode 2 sector data size)
|
||||||
ibuf.clear();
|
ibuf.clear();
|
||||||
|
fo->write(ibuf, PS_HDR_SIZE - fo->getBytesWritten());
|
||||||
// write uncompressed data + pad
|
// write uncompressed data + pad
|
||||||
fo->write(ibuf, PS_HDR_SIZE - sizeof(oh));
|
|
||||||
obuf.clear(ph.u_len, pad);
|
obuf.clear(ph.u_len, pad);
|
||||||
fo->write(obuf, ph.u_len + pad);
|
fo->write(obuf, ph.u_len + pad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+39
-13
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
Copyright (C) 2002-2004 Jens Medoch
|
Copyright (C) 2002-2006 Jens Medoch
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -56,8 +56,12 @@ public:
|
|||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void patch_mips_le(void *b, int blen, const void *old, unsigned new_);
|
virtual void putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len);
|
||||||
|
virtual bool getBkupHeader(unsigned char *src, unsigned char * dst);
|
||||||
|
virtual bool readBkupHeader();
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual bool findBssSection();
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
virtual bool checkFileHeader();
|
virtual bool checkFileHeader();
|
||||||
@@ -84,24 +88,48 @@ protected:
|
|||||||
LE32 sp, fp, gp0, ra, k0;
|
LE32 sp, fp, gp0, ra, k0;
|
||||||
// origin Jap/USA/Europe
|
// origin Jap/USA/Europe
|
||||||
char origin[60];
|
char origin[60];
|
||||||
|
|
||||||
// some safety space after that
|
|
||||||
char pad[8];
|
|
||||||
// backup of the original header (epc - is_len)
|
// backup of the original header (epc - is_len)
|
||||||
|
// id & the upx header ...
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
// for unpack
|
||||||
|
struct ps1_exe_hb_t
|
||||||
|
{
|
||||||
LE32 ih_bkup[10];
|
LE32 ih_bkup[10];
|
||||||
// plus checksum for the backup
|
// plus checksum for the backup
|
||||||
LE32 ih_csum;
|
LE32 ih_csum;
|
||||||
// id & the upx header.
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
struct ps1_exe_chb_t
|
||||||
|
{
|
||||||
|
unsigned char id;
|
||||||
|
unsigned char len;
|
||||||
|
LE16 ih_csum;
|
||||||
|
unsigned char ih_bkup;
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
typedef struct bss_nfo
|
||||||
|
{
|
||||||
|
LE16 hi1, op1, lo1, op2;
|
||||||
|
LE16 hi2, op3, lo2, op4;
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
ps1_exe_t ih, oh;
|
ps1_exe_t ih, oh;
|
||||||
|
ps1_exe_hb_t bh;
|
||||||
|
|
||||||
bool isCon;
|
bool isCon;
|
||||||
bool is32Bit;
|
bool is32Bit;
|
||||||
unsigned overlap;
|
bool buildPart2;
|
||||||
unsigned sa_cnt;
|
bool foundBss;
|
||||||
|
unsigned ram_size;
|
||||||
|
unsigned sa_cnt, overlap;
|
||||||
|
unsigned sz_lunc, sz_lcpr;
|
||||||
|
unsigned pad_code;
|
||||||
|
unsigned bss_start, bss_end;
|
||||||
// filesize-PS_HDR_SIZE
|
// filesize-PS_HDR_SIZE
|
||||||
unsigned fdata_size;
|
unsigned fdata_size;
|
||||||
};
|
};
|
||||||
@@ -113,5 +141,3 @@ protected:
|
|||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+19
-21
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -32,9 +32,10 @@
|
|||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_com.h"
|
#include "p_com.h"
|
||||||
#include "p_sys.h"
|
#include "p_sys.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_sys.h"
|
#include "stub/i086-dos16.sys.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -67,7 +68,6 @@ void PackSys::patchLoader(OutputFile *fo,
|
|||||||
upx_byte *loader, int lsize,
|
upx_byte *loader, int lsize,
|
||||||
unsigned calls)
|
unsigned calls)
|
||||||
{
|
{
|
||||||
const int filter_id = ph.filter;
|
|
||||||
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
||||||
const int d_len = lsize - e_len;
|
const int d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && e_len < 256);
|
assert(e_len > 0 && e_len < 256);
|
||||||
@@ -76,25 +76,22 @@ void PackSys::patchLoader(OutputFile *fo,
|
|||||||
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
|
|
||||||
memcpy(loader,ibuf,6); // copy from orig. header
|
// use some fields of the original file
|
||||||
memcpy(loader+8,ibuf+8,2); // opendos wants this word too
|
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||||
|
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||||
|
|
||||||
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
|
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
|
||||||
|
|
||||||
patch_le16(loader,lsize,"JO",get_le16(ibuf+6)-copy_to-1);
|
linker->defineSymbol("calltrick_calls", calls);
|
||||||
if (filter_id)
|
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||||
{
|
linker->defineSymbol("copy_destination", copy_to);
|
||||||
assert(calls > 0);
|
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead + 1);
|
||||||
patch_le16(loader,lsize,"CT",calls);
|
linker->defineSymbol("original_strategy", get_le16(ibuf + 6));
|
||||||
}
|
|
||||||
|
linker->relocate();
|
||||||
|
loader = getLoader();
|
||||||
|
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
const unsigned jmp_pos = find_le16(loader,e_len,get_le16("JM"));
|
|
||||||
patch_le16(loader,e_len,"JM",ph.u_len+ph.overlap_overhead+2-jmp_pos-2);
|
|
||||||
loader[getLoaderSectionStart("SYSSUBSI") - 1] = (upx_byte) -e_len;
|
|
||||||
patch_le16(loader,e_len,"DI",copy_to);
|
|
||||||
patch_le16(loader,e_len,"SI",ph.c_len+e_len+d_len-1);
|
|
||||||
|
|
||||||
// write loader + compressed file
|
// write loader + compressed file
|
||||||
fo->write(loader,e_len); // entry
|
fo->write(loader,e_len); // entry
|
||||||
fo->write(obuf,ph.c_len);
|
fo->write(obuf,ph.c_len);
|
||||||
@@ -107,12 +104,12 @@ int PackSys::buildLoader(const Filter *ft)
|
|||||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
||||||
addLoader("SYSMAIN1",
|
addLoader("SYSMAIN1",
|
||||||
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
||||||
"SYSMAIN2,SYSSUBSI",
|
"SYSMAIN2",
|
||||||
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
|
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
|
||||||
ft->id ? "SYSCALLT" : "",
|
ft->id ? "SYSCALLT" : "",
|
||||||
"SYSMAIN3,UPX1HEAD,SYSCUTPO,NRV2B160,NRVDDONE,NRVDECO1",
|
"SYSMAIN3,UPX1HEAD,SYSCUTPO,NRV2B160,NRVDDONE,NRVDECO1",
|
||||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||||
"NRVDECO2,NRV2B169",
|
"NRVDECO2",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -125,6 +122,7 @@ int PackSys::buildLoader(const Filter *ft)
|
|||||||
"SYSJUMP1",
|
"SYSJUMP1",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
-22
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,9 +31,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_tmt.h"
|
#include "p_tmt.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_tmt.h"
|
#include "stub/i386-dos32.tmt.h"
|
||||||
|
|
||||||
#define EXTRA_INFO 4 // original entry point
|
#define EXTRA_INFO 4 // original entry point
|
||||||
|
|
||||||
@@ -74,17 +75,25 @@ unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackTmt::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackTmt::buildLoader(const Filter *ft)
|
int PackTmt::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||||
addLoader("IDENTSTR,TMTMAIN1",
|
addLoader("IDENTSTR,TMTMAIN1",
|
||||||
ft->id ? "TMTCALT1" : "",
|
ft->id ? "TMTCALT1" : "",
|
||||||
"TMTMAIN2,UPX1HEAD,TMTCUTPO,+0XXXXXX",
|
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
|
||||||
getDecompressor(),
|
NULL);
|
||||||
"TMTMAIN5",
|
|
||||||
NULL
|
// fake alignment for the start of the decompressor
|
||||||
);
|
linker->defineSymbol("TMTCUTPO", 0x1000);
|
||||||
|
|
||||||
|
addLoader(getDecompressorSections(), "TMTMAIN5", NULL);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
{
|
{
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
@@ -96,6 +105,7 @@ int PackTmt::buildLoader(const Filter *ft)
|
|||||||
"RELOC32J,TMTJUMP1",
|
"RELOC32J,TMTJUMP1",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +185,19 @@ bool PackTmt::canPack()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0)
|
||||||
|
return false;
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -230,30 +253,31 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
compressWithFilters(&ft, 512);
|
compressWithFilters(&ft, 512);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
|
||||||
memcpy(loader,getLoader(),lsize);
|
|
||||||
|
|
||||||
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
||||||
int e_len = getLoaderSectionStart("TMTCUTPO");
|
int e_len = getLoaderSectionStart("TMTCUTPO");
|
||||||
const unsigned d_len = lsize - e_len;
|
const unsigned d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && s_point > 0);
|
assert(e_len > 0 && s_point > 0);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
patch_le32(loader,lsize,"JMPO",ih.entry-(ph.u_len+ph.overlap_overhead+d_len));
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
patchFilter32(loader, lsize, &ft);
|
defineFilterSymbols(linker, &ft);
|
||||||
patchPackHeader(loader,e_len);
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD"));
|
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
|
||||||
patch_le32(loader,e_len,"JMPD",ph.u_len+ph.overlap_overhead-jmp_pos-4);
|
linker->defineSymbol("copy_dest", ph.u_len + ph.overlap_overhead + d_len - 1);
|
||||||
|
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||||
patch_le32(loader,e_len,"ECX0",ph.c_len+d_len);
|
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n",
|
||||||
patch_le32(loader,e_len,"EDI0",ph.u_len+ph.overlap_overhead+d_len-1);
|
|
||||||
patch_le32(loader,e_len,"ESI0",ph.c_len+e_len+d_len-1);
|
|
||||||
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x clen=%x \n\n",
|
|
||||||
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
||||||
|
|
||||||
|
linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead);
|
||||||
|
linker->relocate();
|
||||||
|
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader,getLoader(),lsize);
|
||||||
|
patchPackHeader(loader,e_len);
|
||||||
|
|
||||||
memcpy(&oh,&ih,sizeof(oh));
|
memcpy(&oh,&ih,sizeof(oh));
|
||||||
oh.imagesize = ph.c_len+e_len+d_len; // new size
|
oh.imagesize = ph.c_len + lsize; // new size
|
||||||
oh.entry = s_point; // new entry point
|
oh.entry = s_point; // new entry point
|
||||||
oh.relocsize = 4;
|
oh.relocsize = 4;
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -58,6 +58,7 @@ protected:
|
|||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
unsigned adam_offset;
|
unsigned adam_offset;
|
||||||
int big_relocs;
|
int big_relocs;
|
||||||
|
|||||||
+83
-62
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -32,19 +32,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_tos.h"
|
#include "p_tos.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_t_n2b.h"
|
#include "stub/m68k-atari.tos.h"
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2bs.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2d.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2ds.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2e.h"
|
|
||||||
static const
|
|
||||||
#include "stub/l_t_n2es.h"
|
|
||||||
|
|
||||||
// #define TESTING
|
// #define TESTING
|
||||||
|
|
||||||
@@ -75,27 +66,48 @@ const int *PackTos::getFilters() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const upx_byte *PackTos::getLoader() const
|
Linker* PackTos::newLinker() const
|
||||||
{
|
{
|
||||||
if (M_IS_NRV2B(ph.method))
|
return new ElfLinkerM68k;
|
||||||
return opt->small ? nrv2b_loader_small : nrv2b_loader;
|
|
||||||
if (M_IS_NRV2D(ph.method))
|
|
||||||
return opt->small ? nrv2d_loader_small : nrv2d_loader;
|
|
||||||
if (M_IS_NRV2E(ph.method))
|
|
||||||
return opt->small ? nrv2e_loader_small : nrv2e_loader;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackTos::getLoaderSize() const
|
int PackTos::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
if (M_IS_NRV2B(ph.method))
|
assert(ft->id == 0);
|
||||||
return opt->small ? sizeof(nrv2b_loader_small) : sizeof(nrv2b_loader);
|
|
||||||
if (M_IS_NRV2D(ph.method))
|
const unsigned char *p = NULL;
|
||||||
return opt->small ? sizeof(nrv2d_loader_small) : sizeof(nrv2d_loader);
|
size_t l = 0;
|
||||||
if (M_IS_NRV2E(ph.method))
|
|
||||||
return opt->small ? sizeof(nrv2e_loader_small) : sizeof(nrv2e_loader);
|
p = nrv_loader;
|
||||||
return 0;
|
if (M_IS_NRV2B(ph.method)) {
|
||||||
|
// p = opt->small ? nrv2b_loader_small : nrv2b_loader;
|
||||||
|
// l = opt->small ? sizeof(nrv2b_loader_small) : sizeof(nrv2b_loader);
|
||||||
|
}
|
||||||
|
if (M_IS_NRV2D(ph.method)) {
|
||||||
|
// p = opt->small ? nrv2d_loader_small : nrv2d_loader;
|
||||||
|
// l = opt->small ? sizeof(nrv2d_loader_small) : sizeof(nrv2d_loader);
|
||||||
|
}
|
||||||
|
if (M_IS_NRV2E(ph.method)) {
|
||||||
|
// p = opt->small ? nrv2e_loader_small : nrv2e_loader;
|
||||||
|
// l = opt->small ? sizeof(nrv2e_loader_small) : sizeof(nrv2e_loader);
|
||||||
|
}
|
||||||
|
initLoader(p, l);
|
||||||
|
|
||||||
|
addLoader("tos0",
|
||||||
|
true ? "subql_1d0" : "subqw_1d0",
|
||||||
|
"s_bneloop0",
|
||||||
|
true ? "subql_1d6" : "subqw_1d6",
|
||||||
|
"s_bneloop3",
|
||||||
|
"IDENTSTR,+40,UPX1HEAD",
|
||||||
|
"CUTPOINT",
|
||||||
|
true ? "reloc" : "",
|
||||||
|
"jmpastack",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
freezeLoader();
|
||||||
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -188,6 +200,7 @@ bool PackTos::checkFileHeader()
|
|||||||
// some 68000 opcodes for patching
|
// some 68000 opcodes for patching
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
enum m68k_reg_t {
|
enum m68k_reg_t {
|
||||||
REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
|
REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
|
||||||
REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7
|
REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7
|
||||||
@@ -237,7 +250,6 @@ static unsigned OP_SUBQ_W(int value, int d_reg)
|
|||||||
return 0x5140 | ((value & 7) << 9) | (d_reg & 7);
|
return 0x5140 | ((value & 7) << 9) | (d_reg & 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -299,7 +311,7 @@ unsigned PackTos::patch_d_loop(void *b, int blen,
|
|||||||
set_be32(p, d_value);
|
set_be32(p, d_value);
|
||||||
return d_value;
|
return d_value;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// relocs
|
// relocs
|
||||||
@@ -386,10 +398,8 @@ void PackTos::fileInfo()
|
|||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return;
|
return;
|
||||||
#if !defined(WITH_GUI)
|
|
||||||
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
||||||
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
||||||
#endif /* !defined(WITH_GUI) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -399,6 +409,7 @@ void PackTos::fileInfo()
|
|||||||
|
|
||||||
void PackTos::pack(OutputFile *fo)
|
void PackTos::pack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
|
throwInternalError("atari/tos is currenty broken; this will get fixed in UPX 2.91");
|
||||||
unsigned t;
|
unsigned t;
|
||||||
unsigned nrelocs = 0;
|
unsigned nrelocs = 0;
|
||||||
unsigned relocsize = 0;
|
unsigned relocsize = 0;
|
||||||
@@ -409,6 +420,8 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
const unsigned i_sym = ih.fh_sym;
|
const unsigned i_sym = ih.fh_sym;
|
||||||
const unsigned i_bss = ih.fh_bss;
|
const unsigned i_bss = ih.fh_bss;
|
||||||
|
|
||||||
|
symbols.reset();
|
||||||
|
|
||||||
// read file
|
// read file
|
||||||
const unsigned isize = file_size - i_sym;
|
const unsigned isize = file_size - i_sym;
|
||||||
ibuf.alloc(isize);
|
ibuf.alloc(isize);
|
||||||
@@ -480,14 +493,16 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
// prepare filter
|
// prepare filter
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress (max_match = 65535)
|
// compress (max_match = 65535)
|
||||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
cconf.conf_ucl.max_match = 65535;
|
||||||
|
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||||
|
|
||||||
// get loader
|
// get loader
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
const unsigned e_len = get_be16(getLoader()+lsize-6);
|
const unsigned e_len = getLoaderSectionStart("CUTPOINT");
|
||||||
const unsigned d_len = get_be16(getLoader()+lsize-4);
|
const unsigned d_len = lsize - e_len;
|
||||||
const unsigned decomp_offset = get_be16(getLoader()+lsize-2);
|
const unsigned decomp_offset = linker->getSymbolOffset("decompr_start") - e_len;
|
||||||
assert(e_len + d_len == lsize - 6);
|
assert(decomp_offset != 0xdeaddead);
|
||||||
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
assert((e_len & 3) == 0 && (d_len & 1) == 0);
|
||||||
|
|
||||||
// The decompressed data will now get placed at this offset:
|
// The decompressed data will now get placed at this offset:
|
||||||
@@ -508,7 +523,6 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
|
|
||||||
// append decompressor (part 2 of loader)
|
// append decompressor (part 2 of loader)
|
||||||
const unsigned d_off = o_data;
|
const unsigned d_off = o_data;
|
||||||
memcpy(obuf+d_off, getLoader()+e_len, d_len);
|
|
||||||
o_data += d_len;
|
o_data += d_len;
|
||||||
|
|
||||||
// dword align the len of the final data segment
|
// dword align the len of the final data segment
|
||||||
@@ -540,22 +554,12 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
while (o_bss & 3)
|
while (o_bss & 3)
|
||||||
o_bss++;
|
o_bss++;
|
||||||
|
|
||||||
// prepare loader
|
|
||||||
MemBuffer loader(o_text);
|
|
||||||
memcpy(loader, getLoader(), o_text);
|
|
||||||
|
|
||||||
// patch loader
|
|
||||||
int tmp = patchPackHeader(loader, o_text);
|
|
||||||
assert(tmp + 32 == (int)o_text); UNUSED(tmp);
|
|
||||||
patchVersionYear(loader, o_text);
|
|
||||||
if (!opt->small)
|
|
||||||
patchVersion(loader, o_text);
|
|
||||||
// patch "subq.l #1,d6" or "subq.w #1,d6" - see "up41" below
|
// patch "subq.l #1,d6" or "subq.w #1,d6" - see "up41" below
|
||||||
const unsigned dirty_bss_d6 =
|
const unsigned dirty_bss_d6 = dirty_bss / dirty_bss_align;
|
||||||
patch_d_subq(loader, o_text, REG_D6, dirty_bss / dirty_bss_align, "u4");
|
// FIXME patch_d_subq(loader, o_text, REG_D6, dirty_bss / dirty_bss_align, "u4");
|
||||||
patch_be32(loader, o_text, "up31", d_off + offset + decomp_offset);
|
linker->defineSymbol("up31", d_off + offset + decomp_offset);
|
||||||
if (opt->small)
|
if (opt->small)
|
||||||
patch_d_loop(loader, o_text, REG_D0, o_data/4, "up22", "u1");
|
; // patch_d_loop(loader, o_text, REG_D0, o_data/4, "up22", "u1");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (o_data <= 160)
|
if (o_data <= 160)
|
||||||
@@ -567,19 +571,26 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
loop1--;
|
loop1--;
|
||||||
loop2 = 160;
|
loop2 = 160;
|
||||||
}
|
}
|
||||||
patch_be16(loader, o_text, "u2", OP_MOVEQ(loop2/4-1, REG_D0)); // moveq.l #X,d0
|
linker->defineSymbol("copy_remain", loop2 / 4 - 1);
|
||||||
patch_d_loop(loader, o_text, REG_D0, loop1, "up22", "u1");
|
//patch_be16(loader, o_text, "u2", OP_MOVEQ(loop2/4-1, REG_D0)); // moveq.l #X,d0
|
||||||
|
//patch_d_loop(loader, o_text, REG_D0, loop1, "up22", "u1");
|
||||||
}
|
}
|
||||||
patch_be32(loader,o_text,"up21",o_data + offset);
|
linker->defineSymbol("up22", opt->small ? o_data / 4 : (o_data - 1) / 160);
|
||||||
patch_be32(loader,o_text,"up13",i_bss); // p_blen
|
linker->defineSymbol("up21", o_data + offset);
|
||||||
patch_be32(loader,o_text,"up12",i_data); // p_dlen
|
linker->defineSymbol("up13", i_bss); // p_blen
|
||||||
patch_be32(loader,o_text,"up11",i_text); // p_tlen
|
linker->defineSymbol("up12", i_data); // p_dlen
|
||||||
|
linker->defineSymbol("up11", i_text); // p_tlen
|
||||||
|
|
||||||
|
const unsigned clear_size = linker->getSymbolOffset("clear_bss_end") -
|
||||||
|
linker->getSymbolOffset("clear_bss");
|
||||||
|
linker->defineSymbol("copy_to_stack_len", clear_size / 2 - 1);
|
||||||
|
linker->defineSymbol("clear_bss_size_p4", clear_size + 4);
|
||||||
|
|
||||||
// patch decompressor
|
// patch decompressor
|
||||||
upx_byte *p = obuf + d_off;
|
//upx_byte *p = obuf + d_off;
|
||||||
// patch "moveq.l #1,d5" or "jmp (ASTACK)"
|
// patch "moveq.l #1,d5" or "jmp (ASTACK)"
|
||||||
patch_be16(p, d_len, "u3", (nrelocs > 0) ? OP_MOVEQ(1, REG_D5) : OP_JMP(REG_A7));
|
//patch_be16(p, d_len, "u3", (nrelocs > 0) ? OP_MOVEQ(1, REG_D5) : OP_JMP(REG_A7));
|
||||||
patch_be32(p, d_len, "up41", dirty_bss_d6);
|
linker->defineSymbol("up41", dirty_bss_d6);
|
||||||
|
|
||||||
// set new file_hdr
|
// set new file_hdr
|
||||||
memcpy(&oh, &ih, FH_SIZE);
|
memcpy(&oh, &ih, FH_SIZE);
|
||||||
@@ -609,9 +620,19 @@ void PackTos::pack(OutputFile *fo)
|
|||||||
o_text, o_data, o_bss, dirty_bss, (int)oh.fh_flag);
|
o_text, o_data, o_bss, dirty_bss, (int)oh.fh_flag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
linker->relocate();
|
||||||
|
// prepare loader
|
||||||
|
MemBuffer loader(o_text);
|
||||||
|
memcpy(loader, getLoader(), o_text);
|
||||||
|
memcpy(obuf+d_off, getLoader() + e_len, d_len);
|
||||||
|
|
||||||
|
patchPackHeader(loader, o_text);
|
||||||
|
|
||||||
// write new file header, loader and compressed file
|
// write new file header, loader and compressed file
|
||||||
fo->write(&oh, FH_SIZE);
|
fo->write(&oh, FH_SIZE);
|
||||||
fo->write(loader, o_text); // entry
|
fo->write(loader, o_text); // entry
|
||||||
|
if (opt->debug.dump_stub_loader)
|
||||||
|
OutputFile::dump(opt->debug.dump_stub_loader, loader, o_text);
|
||||||
fo->write(obuf, o_data); // compressed + decompressor
|
fo->write(obuf, o_data); // compressed + decompressor
|
||||||
|
|
||||||
// write empty relocation fixup
|
// write empty relocation fixup
|
||||||
|
|||||||
+22
-4
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -54,8 +54,8 @@ public:
|
|||||||
virtual void fileInfo();
|
virtual void fileInfo();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const upx_byte *getLoader() const;
|
virtual Linker* newLinker() const;
|
||||||
virtual int getLoaderSize() const;
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
virtual bool checkFileHeader();
|
virtual bool checkFileHeader();
|
||||||
@@ -75,6 +75,24 @@ protected:
|
|||||||
|
|
||||||
tos_header_t ih, oh;
|
tos_header_t ih, oh;
|
||||||
|
|
||||||
|
struct LinkerSymbols
|
||||||
|
{
|
||||||
|
enum { LOOP_UNKNOWN, LOOP_SUBQ_L, LOOP_SUBQ_W, LOOP_DBRA };
|
||||||
|
// before linker->relocate()
|
||||||
|
unsigned loop1_count; int loop1_mode;
|
||||||
|
unsigned loop2_count; int loop2_mode;
|
||||||
|
unsigned loop3_count; int loop3_mode;
|
||||||
|
// after linker->relocate()
|
||||||
|
unsigned copy_to_stack_len;
|
||||||
|
unsigned flush_cache_rts_offset;
|
||||||
|
unsigned clear_bss_size_p4;
|
||||||
|
unsigned clear_dirty_stack_len;
|
||||||
|
// FIXME: up11 etc.
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
LinkerSymbols symbols;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned patch_d_subq(void *l, int llen, int, unsigned, const char*);
|
unsigned patch_d_subq(void *l, int llen, int, unsigned, const char*);
|
||||||
unsigned patch_d_loop(void *l, int llen, int, unsigned, const char*, const char*);
|
unsigned patch_d_loop(void *l, int llen, int, unsigned, const char*, const char*);
|
||||||
|
|||||||
+28
-29
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -225,7 +225,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
|||||||
void
|
void
|
||||||
PackUnix::patchLoaderChecksum()
|
PackUnix::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = &linfo;
|
l_info *const lp = &linfo;
|
||||||
// checksum for loader; also some PackHeader info
|
// checksum for loader; also some PackHeader info
|
||||||
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
||||||
@@ -236,11 +236,10 @@ PackUnix::patchLoaderChecksum()
|
|||||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackUnix::pack3(OutputFile *fo, Filter &ft)
|
void PackUnix::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||||
{
|
{
|
||||||
upx_byte const *p = getLoader();
|
upx_byte *p = getLoader();
|
||||||
lsize = getLoaderSize();
|
lsize = getLoaderSize();
|
||||||
patchFilter32(const_cast<upx_byte *>(p), lsize, &ft);
|
|
||||||
updateLoader(fo);
|
updateLoader(fo);
|
||||||
patchLoaderChecksum();
|
patchLoaderChecksum();
|
||||||
fo->write(p, lsize);
|
fo->write(p, lsize);
|
||||||
@@ -305,16 +304,16 @@ void PackUnix::packExtent(
|
|||||||
unsigned &total_out,
|
unsigned &total_out,
|
||||||
Filter *ft,
|
Filter *ft,
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
unsigned hdr_ulen
|
unsigned hdr_u_len
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned const init_u_adler = ph.u_adler;
|
unsigned const init_u_adler = ph.u_adler;
|
||||||
unsigned const init_c_adler = ph.c_adler;
|
unsigned const init_c_adler = ph.c_adler;
|
||||||
MemBuffer hdr_ibuf;
|
MemBuffer hdr_ibuf;
|
||||||
if (hdr_ulen) {
|
if (hdr_u_len) {
|
||||||
hdr_ibuf.alloc(hdr_ulen);
|
hdr_ibuf.alloc(hdr_u_len);
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
int l = fi->readx(hdr_ibuf, hdr_ulen);
|
int l = fi->readx(hdr_ibuf, hdr_u_len);
|
||||||
(void)l;
|
(void)l;
|
||||||
}
|
}
|
||||||
fi->seek(x.offset, SEEK_SET);
|
fi->seek(x.offset, SEEK_SET);
|
||||||
@@ -347,8 +346,8 @@ void PackUnix::packExtent(
|
|||||||
ft->cto = 0;
|
ft->cto = 0;
|
||||||
|
|
||||||
compressWithFilters(ft, OVERHEAD, strategy,
|
compressWithFilters(ft, OVERHEAD, strategy,
|
||||||
NULL, 0, 0, 0, 0, // those 5 args are the defaults
|
NULL, NULL, 0, 0, // those 4 args are the defaults
|
||||||
hdr_ibuf, hdr_ulen);
|
hdr_ibuf, hdr_u_len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(void) compress(ibuf, obuf); // ignore return value
|
(void) compress(ibuf, obuf); // ignore return value
|
||||||
@@ -371,31 +370,31 @@ void PackUnix::packExtent(
|
|||||||
|
|
||||||
// write block sizes
|
// write block sizes
|
||||||
b_info tmp;
|
b_info tmp;
|
||||||
if (hdr_ulen) {
|
if (hdr_u_len) {
|
||||||
unsigned hdr_clen;
|
unsigned hdr_c_len = 0;
|
||||||
MemBuffer hdr_obuf;
|
MemBuffer hdr_obuf;
|
||||||
unsigned result[16];
|
hdr_obuf.allocForCompression(hdr_u_len);
|
||||||
upx_compress_config_t conf;
|
int r = upx_compress(hdr_ibuf, hdr_u_len, hdr_obuf, &hdr_c_len, 0,
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
ph.method, 10, NULL, NULL);
|
||||||
hdr_obuf.allocForCompression(hdr_ulen);
|
if (r != UPX_E_OK)
|
||||||
int r = upx_compress(hdr_ibuf, hdr_ulen, hdr_obuf, &hdr_clen, 0,
|
throwInternalError("header compression failed");
|
||||||
ph.method, 10, &conf, result);
|
if (hdr_c_len >= hdr_u_len)
|
||||||
(void)r;
|
throwInternalError("header compression size increase");
|
||||||
ph.saved_u_adler = upx_adler32(hdr_ibuf, hdr_ulen, init_u_adler);
|
ph.saved_u_adler = upx_adler32(hdr_ibuf, hdr_u_len, init_u_adler);
|
||||||
ph.saved_c_adler = upx_adler32(hdr_obuf, hdr_clen, init_c_adler);
|
ph.saved_c_adler = upx_adler32(hdr_obuf, hdr_c_len, init_c_adler);
|
||||||
ph.u_adler = upx_adler32(ibuf, ph.u_len, ph.saved_u_adler);
|
ph.u_adler = upx_adler32(ibuf, ph.u_len, ph.saved_u_adler);
|
||||||
ph.c_adler = upx_adler32(obuf, ph.c_len, ph.saved_c_adler);
|
ph.c_adler = upx_adler32(obuf, ph.c_len, ph.saved_c_adler);
|
||||||
end_u_adler = ph.u_adler;
|
end_u_adler = ph.u_adler;
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
set_native32(&tmp.sz_unc, hdr_ulen);
|
set_native32(&tmp.sz_unc, hdr_u_len);
|
||||||
set_native32(&tmp.sz_cpr, hdr_clen);
|
set_native32(&tmp.sz_cpr, hdr_c_len);
|
||||||
tmp.b_method = (unsigned char) ph.method;
|
tmp.b_method = (unsigned char) ph.method;
|
||||||
fo->write(&tmp, sizeof(tmp));
|
fo->write(&tmp, sizeof(tmp));
|
||||||
b_len += sizeof(b_info);
|
b_len += sizeof(b_info);
|
||||||
fo->write(hdr_obuf, hdr_clen);
|
fo->write(hdr_obuf, hdr_c_len);
|
||||||
total_out += hdr_clen;
|
total_out += hdr_c_len;
|
||||||
total_in += hdr_ulen;
|
total_in += hdr_u_len;
|
||||||
hdr_ulen = 0; // compress hdr one time only
|
hdr_u_len = 0; // compress hdr one time only
|
||||||
}
|
}
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
set_native32(&tmp.sz_unc, ph.u_len);
|
set_native32(&tmp.sz_unc, ph.u_len);
|
||||||
|
|||||||
+2
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
|
|||||||
+52
-15
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 2004 John Reiser
|
Copyright (C) 2004-2006 John Reiser
|
||||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,9 +36,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_vmlinx.h"
|
#include "p_vmlinx.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_vmlinx.h"
|
#include "stub/i386-linux.kernel.vmlinux.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -125,7 +126,7 @@ bool PackVmlinuxI386::canPack()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
phdri = new Elf32_Phdr[(unsigned) ehdri.e_phnum];
|
phdri = new Elf_LE32_Phdr[(unsigned) ehdri.e_phnum];
|
||||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||||
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
||||||
|
|
||||||
@@ -153,6 +154,13 @@ bool PackVmlinuxI386::canPack()
|
|||||||
return 0 < n_ptload;
|
return 0 < n_ptload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackVmlinuxI386::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackVmlinuxI386::buildLoader(const Filter *ft)
|
int PackVmlinuxI386::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
@@ -160,7 +168,7 @@ int PackVmlinuxI386::buildLoader(const Filter *ft)
|
|||||||
addLoader("LINUX000",
|
addLoader("LINUX000",
|
||||||
(0x40==(0xf0 & ft->id)) ? "LXCKLLT1" : (ft->id ? "LXCALLT1" : ""),
|
(0x40==(0xf0 & ft->id)) ? "LXCKLLT1" : (ft->id ? "LXCALLT1" : ""),
|
||||||
"LXMOVEUP",
|
"LXMOVEUP",
|
||||||
getDecompressor(),
|
getDecompressorSections(),
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -175,10 +183,25 @@ int PackVmlinuxI386::buildLoader(const Filter *ft)
|
|||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("LINUX990,IDENTSTR,UPX1HEAD", NULL);
|
addLoader("LINUX990,IDENTSTR,UPX1HEAD", NULL);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0)
|
||||||
|
return false;
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PackVmlinuxI386::pack(OutputFile *fo)
|
void PackVmlinuxI386::pack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
unsigned fo_off = 0;
|
unsigned fo_off = 0;
|
||||||
@@ -219,15 +242,23 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
ft.buf_len = ph.u_len;
|
ft.buf_len = ph.u_len;
|
||||||
ft.addvalue = 0; // we are independent of actual runtime address; see ckt32
|
ft.addvalue = 0; // we are independent of actual runtime address; see ckt32
|
||||||
|
|
||||||
compressWithFilters(&ft, 1 << 20);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
|
|
||||||
|
defineFilterSymbols(linker, &ft);
|
||||||
|
if (0x40==(0xf0 & ft.id)) {
|
||||||
|
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
||||||
|
}
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
linker->relocate();
|
||||||
|
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
memcpy(loader, getLoader(), lsize);
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
|
||||||
patchPackHeader(loader, lsize);
|
patchPackHeader(loader, lsize);
|
||||||
patch_le32(loader, lsize, "ULEN", ph.u_len);
|
|
||||||
patchFilter32(loader, lsize, &ft);
|
|
||||||
|
|
||||||
while (0!=*p++) ;
|
while (0!=*p++) ;
|
||||||
shdro[1].sh_name = ptr_diff(p, shstrtab);
|
shdro[1].sh_name = ptr_diff(p, shstrtab);
|
||||||
@@ -278,7 +309,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
ph.level = 1;
|
ph.level = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compress(ibuf, obuf);
|
compress(ibuf, obuf, &cconf);
|
||||||
ph.level = old_level;
|
ph.level = old_level;
|
||||||
|
|
||||||
// while (0!=*p++) ; // name is the same
|
// while (0!=*p++) ; // name is the same
|
||||||
@@ -294,7 +325,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||||||
shdro[4].sh_name = ptr_diff(p, shstrtab);
|
shdro[4].sh_name = ptr_diff(p, shstrtab);
|
||||||
shdro[4].sh_type = Elf32_Shdr::SHT_STRTAB;
|
shdro[4].sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||||
shdro[4].sh_offset = fo_off;
|
shdro[4].sh_offset = fo_off;
|
||||||
shdro[4].sh_size = 1+ sizeof(shstrtab); // 1+: terminating '\0'
|
shdro[4].sh_size = sizeof(shstrtab); // already includes terminating '\0'
|
||||||
shdro[4].sh_addralign = 1;
|
shdro[4].sh_addralign = 1;
|
||||||
fo->write(shstrtab, shdro[4].sh_size); fo_off += shdro[4].sh_size;
|
fo->write(shstrtab, shdro[4].sh_size); fo_off += shdro[4].sh_size;
|
||||||
|
|
||||||
@@ -355,8 +386,8 @@ int PackVmlinuxI386::canUnpack()
|
|||||||
|
|
||||||
// find the .shstrtab section
|
// find the .shstrtab section
|
||||||
char shstrtab[40];
|
char shstrtab[40];
|
||||||
Elf32_Shdr *p, *p_shstrtab=0;
|
Elf_LE32_Shdr *p, *p_shstrtab=0;
|
||||||
shdri = new Elf32_Shdr[(unsigned) ehdri.e_shnum];
|
shdri = new Elf_LE32_Shdr[(unsigned) ehdri.e_shnum];
|
||||||
fi->seek(ehdri.e_shoff, SEEK_SET);
|
fi->seek(ehdri.e_shoff, SEEK_SET);
|
||||||
fi->readx(shdri, ehdri.e_shnum * sizeof(*shdri));
|
fi->readx(shdri, ehdri.e_shnum * sizeof(*shdri));
|
||||||
int j;
|
int j;
|
||||||
@@ -476,6 +507,7 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
//targets := vmlinux upx-head.o upx-piggy.o
|
//targets := vmlinux upx-head.o upx-piggy.o
|
||||||
//
|
//
|
||||||
//LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32
|
//LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32
|
||||||
|
//EXTRA_AFLAGS += -DIMAGE_OFFSET=$(IMAGE_OFFSET)
|
||||||
//
|
//
|
||||||
//$(obj)/vmlinux: $(obj)/upx-head.o $(obj)/upx-piggy.o FORCE
|
//$(obj)/vmlinux: $(obj)/upx-head.o $(obj)/upx-piggy.o FORCE
|
||||||
// $(call if_changed,ld)
|
// $(call if_changed,ld)
|
||||||
@@ -484,6 +516,7 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
//$(obj)/upx-piggy.o: vmlinux FORCE
|
//$(obj)/upx-piggy.o: vmlinux FORCE
|
||||||
// rm -f $@
|
// rm -f $@
|
||||||
// upx --best -o $@ $<
|
// upx --best -o $@ $<
|
||||||
|
// touch $@
|
||||||
//-----
|
//-----
|
||||||
//
|
//
|
||||||
//----- arch/i386/boot/compressed/upx-head.S
|
//----- arch/i386/boot/compressed/upx-head.S
|
||||||
@@ -516,7 +549,10 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
//
|
//
|
||||||
// pushl $0; popf # subsumes "cli; cld"; also clears NT for buggy BIOS
|
// pushl $0; popf # subsumes "cli; cld"; also clears NT for buggy BIOS
|
||||||
//
|
//
|
||||||
// movl $ 0x100000,%eax # destination of uncompression (and entry point)
|
//#ifndef IMAGE_OFFSET /*{*/
|
||||||
|
//#define IMAGE_OFFSET 0x100000
|
||||||
|
//#endif /*}*/
|
||||||
|
// movl $ IMAGE_OFFSET,%eax # destination of uncompression (and entry point)
|
||||||
// push %cs
|
// push %cs
|
||||||
/* Fall into .text of upx-compressed vmlinux. */
|
/* Fall into .text of upx-compressed vmlinux. */
|
||||||
//-----
|
//-----
|
||||||
@@ -558,6 +594,7 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
//upx-piggy.o: $(SYSTEM)
|
//upx-piggy.o: $(SYSTEM)
|
||||||
// $(RM) -f $@
|
// $(RM) -f $@
|
||||||
// upx --best -o $@ $<
|
// upx --best -o $@ $<
|
||||||
|
// touch $@
|
||||||
//
|
//
|
||||||
//clean:
|
//clean:
|
||||||
// rm -f vmlinux bvmlinux _tmp_*
|
// rm -f vmlinux bvmlinux _tmp_*
|
||||||
|
|||||||
+9
-8
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -55,17 +55,18 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
// virtual const upx_byte *getLoader() const;
|
// virtual const upx_byte *getLoader() const;
|
||||||
// virtual int getLoaderSize() const;
|
// virtual int getLoaderSize() const;
|
||||||
|
|
||||||
int n_ptload;
|
int n_ptload;
|
||||||
unsigned sz_ptload;
|
unsigned sz_ptload;
|
||||||
Elf32_Phdr *phdri; // from input file
|
Elf_LE32_Phdr *phdri; // from input file
|
||||||
Elf32_Shdr *shdri; // from input file
|
Elf_LE32_Shdr *shdri; // from input file
|
||||||
Elf32_Shdr *p_text;
|
Elf_LE32_Shdr *p_text;
|
||||||
Elf32_Shdr *p_note0;
|
Elf_LE32_Shdr *p_note0;
|
||||||
Elf32_Shdr *p_note1;
|
Elf_LE32_Shdr *p_note1;
|
||||||
Elf32_Ehdr ehdri; // from input file
|
Elf_LE32_Ehdr ehdri; // from input file
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+89
-38
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -32,10 +32,11 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_vmlinz.h"
|
#include "p_vmlinz.h"
|
||||||
|
#include "linker.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_vmlinz.h"
|
#include "stub/i386-linux.kernel.vmlinuz.h"
|
||||||
|
|
||||||
static const unsigned kernel_entry = 0x100000;
|
static const unsigned kernel_entry = 0x100000;
|
||||||
static const unsigned stack_offset_during_uncompression = 0x9000;
|
static const unsigned stack_offset_during_uncompression = 0x9000;
|
||||||
@@ -164,7 +165,7 @@ int PackVmlinuzI386::decompressKernel()
|
|||||||
fd = dup(fi->getFd());
|
fd = dup(fi->getFd());
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
break;
|
break;
|
||||||
gzFile zf = gzdopen(fd, "r");
|
gzFile zf = gzdopen(fd, "rb");
|
||||||
if (zf == NULL)
|
if (zf == NULL)
|
||||||
break;
|
break;
|
||||||
// estimate gzip-decompressed kernel size & alloc buffer
|
// estimate gzip-decompressed kernel size & alloc buffer
|
||||||
@@ -242,6 +243,12 @@ void PackVmlinuzI386::readKernel()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackVmlinuzI386::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// vmlinuz specific
|
// vmlinuz specific
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -253,7 +260,7 @@ int PackVmlinuzI386::buildLoader(const Filter *ft)
|
|||||||
addLoader("LINUZ000",
|
addLoader("LINUZ000",
|
||||||
ft->id ? "LZCALLT1" : "",
|
ft->id ? "LZCALLT1" : "",
|
||||||
"LZIMAGE0",
|
"LZIMAGE0",
|
||||||
getDecompressor(),
|
getDecompressorSections(),
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -263,10 +270,24 @@ int PackVmlinuzI386::buildLoader(const Filter *ft)
|
|||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("LINUZ990,IDENTSTR,UPX1HEAD", NULL);
|
addLoader("LINUZ990,IDENTSTR,UPX1HEAD", NULL);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0)
|
||||||
|
return false;
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void PackVmlinuzI386::pack(OutputFile *fo)
|
void PackVmlinuzI386::pack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
readKernel();
|
readKernel();
|
||||||
@@ -275,18 +296,25 @@ void PackVmlinuzI386::pack(OutputFile *fo)
|
|||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
ft.buf_len = ph.u_len;
|
ft.buf_len = ph.u_len;
|
||||||
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
|
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
|
||||||
|
|
||||||
// compress
|
// compress
|
||||||
compressWithFilters(&ft, 1 << 20);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
|
|
||||||
|
defineFilterSymbols(linker, &ft);
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
linker->defineSymbol("src_for_decompressor", zimage_offset + lsize);
|
||||||
|
linker->defineSymbol("original_entry", kernel_entry);
|
||||||
|
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
|
||||||
|
linker->relocate();
|
||||||
|
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
memcpy(loader, getLoader(), lsize);
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
|
||||||
patchPackHeader(loader, lsize);
|
patchPackHeader(loader, lsize);
|
||||||
patchFilter32(loader, lsize, &ft);
|
|
||||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
|
||||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
|
||||||
patch_le32(loader, lsize, "STAK", stack_offset_during_uncompression);
|
|
||||||
|
|
||||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||||
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16) / 16;
|
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16) / 16;
|
||||||
@@ -320,10 +348,15 @@ int PackBvmlinuzI386::buildLoader(const Filter *ft)
|
|||||||
addLoader("LINUZ000",
|
addLoader("LINUZ000",
|
||||||
(0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
|
(0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
|
||||||
"LBZIMAGE,IDENTSTR",
|
"LBZIMAGE,IDENTSTR",
|
||||||
"+40D++++", // align the stuff to 4 byte boundary
|
"+40", // align the stuff to 4 byte boundary
|
||||||
"UPX1HEAD", // 32 byte
|
"UPX1HEAD", // 32 byte
|
||||||
"LZCUTPOI,+0000000",
|
"LZCUTPOI",
|
||||||
getDecompressor(),
|
NULL);
|
||||||
|
|
||||||
|
// fake alignment for the start of the decompressor
|
||||||
|
linker->defineSymbol("LZCUTPOI", 0x1000);
|
||||||
|
|
||||||
|
addLoader(getDecompressorSections(),
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
@@ -338,6 +371,7 @@ int PackBvmlinuzI386::buildLoader(const Filter *ft)
|
|||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("LINUZ990", NULL);
|
addLoader("LINUZ990", NULL);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,55 +384,72 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
|
|||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
ft.buf_len = ph.u_len;
|
ft.buf_len = ph.u_len;
|
||||||
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
|
ft.addvalue = kernel_entry; // saves 4 bytes in unfilter code
|
||||||
// compress
|
|
||||||
compressWithFilters(&ft, 512);
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
|
// limit stack size needed for runtime decompression
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
|
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||||
|
|
||||||
// align everything to dword boundary - it is easier to handle
|
// align everything to dword boundary - it is easier to handle
|
||||||
unsigned clen = ph.c_len;
|
unsigned c_len = ph.c_len;
|
||||||
memset(obuf + clen, 0, 4);
|
memset(obuf + c_len, 0, 4);
|
||||||
clen = ALIGN_UP(clen, 4);
|
c_len = ALIGN_UP(c_len, 4);
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
const unsigned lsize = getLoaderSize();
|
||||||
MemBuffer loader(lsize);
|
|
||||||
memcpy(loader, getLoader(), lsize);
|
|
||||||
|
|
||||||
patchFilter32(loader, lsize, &ft);
|
if (ph.method == M_LZMA) {
|
||||||
patchPackHeader(loader, lsize);
|
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||||
|
unsigned const properties = // lc, lp, pb, dummy
|
||||||
|
(res->lit_context_bits << 0) |
|
||||||
|
(res->lit_pos_bits << 8) |
|
||||||
|
(res->pos_bits << 16);
|
||||||
|
linker->defineSymbol("lzma_properties", properties);
|
||||||
|
// -2 for properties
|
||||||
|
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||||
|
linker->defineSymbol("lzma_u_len", ph.u_len);
|
||||||
|
unsigned const stack = getDecompressorWrkmemSize();
|
||||||
|
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
||||||
|
}
|
||||||
|
|
||||||
const int e_len = getLoaderSectionStart("LZCUTPOI");
|
const int e_len = getLoaderSectionStart("LZCUTPOI");
|
||||||
assert(e_len > 0);
|
assert(e_len > 0);
|
||||||
|
|
||||||
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4);
|
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4);
|
||||||
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16);
|
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16);
|
||||||
const unsigned copy_size = clen + d_len4;
|
const unsigned copy_size = c_len + d_len4;
|
||||||
const unsigned edi = decompr_pos + d_len4 - 4; // copy to
|
const unsigned edi = decompr_pos + d_len4 - 4; // copy to
|
||||||
const unsigned esi = ALIGN_UP(clen + lsize, 4) - 4; // copy from
|
const unsigned esi = ALIGN_UP(c_len + lsize, 4) - 4; // copy from
|
||||||
|
|
||||||
unsigned jpos = find_le32(loader, e_len, get_le32("JMPD"));
|
linker->defineSymbol("decompressor", decompr_pos);
|
||||||
patch_le32(loader, e_len, "JMPD", decompr_pos - jpos - 4);
|
linker->defineSymbol("src_for_decompressor", bzimage_offset + decompr_pos - c_len);
|
||||||
|
linker->defineSymbol("words_to_copy", copy_size / 4);
|
||||||
patch_le32(loader, e_len, "ESI1", bzimage_offset + decompr_pos - clen);
|
linker->defineSymbol("copy_dest", bzimage_offset + edi);
|
||||||
patch_le32(loader, e_len, "ECX0", copy_size / 4);
|
linker->defineSymbol("copy_source", bzimage_offset + esi);
|
||||||
patch_le32(loader, e_len, "EDI0", bzimage_offset + edi);
|
|
||||||
patch_le32(loader, e_len, "ESI0", bzimage_offset + esi);
|
|
||||||
|
|
||||||
|
defineFilterSymbols(linker, &ft);
|
||||||
if (0x40==(0xf0 & ft.id)) {
|
if (0x40==(0xf0 & ft.id)) {
|
||||||
patch_le32(loader, e_len, "ULEN", ph.u_len);
|
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
||||||
}
|
}
|
||||||
patch_le32(loader, e_len, "KEIP", kernel_entry);
|
defineDecompressorSymbols();
|
||||||
patch_le32(loader, e_len, "STAK", stack_offset_during_uncompression);
|
linker->defineSymbol("original_entry", kernel_entry);
|
||||||
|
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
|
||||||
|
linker->relocate();
|
||||||
|
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||||
bs->sys_size = (ALIGN_UP(lsize + clen, 16) / 16) & 0xffff;
|
bs->sys_size = (ALIGN_UP(lsize + c_len, 16) / 16) & 0xffff;
|
||||||
|
|
||||||
fo->write(setup_buf, setup_buf.getSize());
|
fo->write(setup_buf, setup_buf.getSize());
|
||||||
fo->write(loader, e_len);
|
fo->write(loader, e_len);
|
||||||
fo->write(obuf, clen);
|
fo->write(obuf, c_len);
|
||||||
fo->write(loader + e_len, lsize - e_len);
|
fo->write(loader + e_len, lsize - e_len);
|
||||||
#if 0
|
#if 0
|
||||||
printf("%-13s: setup : %8ld bytes\n", getName(), (long) setup_buf.getSize());
|
printf("%-13s: setup : %8ld bytes\n", getName(), (long) setup_buf.getSize());
|
||||||
printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len);
|
printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len);
|
||||||
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) clen);
|
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) c_len);
|
||||||
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) (lsize - e_len));
|
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) (lsize - e_len));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -57,6 +57,8 @@ protected:
|
|||||||
virtual void readKernel();
|
virtual void readKernel();
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
// virtual const upx_byte *getLoader() const;
|
// virtual const upx_byte *getLoader() const;
|
||||||
// virtual int getLoaderSize() const;
|
// virtual int getLoaderSize() const;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
|
|||||||
+10
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_w16ne.h"
|
#include "p_w16ne.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -67,10 +68,17 @@ int PackW16Ne::buildLoader(const Filter *ft)
|
|||||||
// addLoader("...");
|
// addLoader("...");
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackW16Ne::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|||||||
+3
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -55,6 +55,7 @@ protected:
|
|||||||
virtual int readFileHeader(void);
|
virtual int readFileHeader(void);
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+84
-1421
File diff suppressed because it is too large
Load Diff
+8
-188
@@ -29,226 +29,46 @@
|
|||||||
#ifndef __UPX_P_W32PE_H
|
#ifndef __UPX_P_W32PE_H
|
||||||
#define __UPX_P_W32PE_H
|
#define __UPX_P_W32PE_H
|
||||||
|
|
||||||
|
|
||||||
class PackW32Pe_Interval;
|
|
||||||
class PackW32Pe_Reloc;
|
|
||||||
class PackW32Pe_Resource;
|
|
||||||
class PackW32Pe_Export;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// w32/pe
|
// w32/pe
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackW32Pe : public Packer
|
class PackW32Pe : public PeFile
|
||||||
{
|
{
|
||||||
typedef Packer super;
|
typedef PeFile super;;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackW32Pe(InputFile *f);
|
PackW32Pe(InputFile *f);
|
||||||
~PackW32Pe();
|
~PackW32Pe();
|
||||||
virtual int getVersion() const { return 13; }
|
|
||||||
virtual int getFormat() const { return UPX_F_WIN32_PE; }
|
virtual int getFormat() const { return UPX_F_WIN32_PE; }
|
||||||
virtual const char *getName() const { return isrtm ? "rtm32/pe" : "win32/pe"; }
|
virtual const char *getName() const { return isrtm ? "rtm32/pe" : "win32/pe"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
virtual void pack(OutputFile *fo);
|
virtual void pack(OutputFile *fo);
|
||||||
virtual void unpack(OutputFile *fo);
|
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
// unpacker capabilities
|
|
||||||
virtual bool canUnpackVersion(int version) const
|
|
||||||
{ return (version >= 12 && version <= 13); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
virtual bool testUnpackVersion(int version) const;
|
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
unsigned pe_offset;
|
|
||||||
bool isrtm;
|
bool isrtm;
|
||||||
|
|
||||||
unsigned processImports();
|
virtual unsigned processImports();
|
||||||
void processImports(unsigned);
|
virtual void processImports(unsigned, unsigned);
|
||||||
void rebuildImports(upx_byte *&);
|
virtual void rebuildImports(upx_byte *&);
|
||||||
upx_byte *oimport;
|
|
||||||
unsigned soimport;
|
|
||||||
upx_byte *oimpdlls;
|
|
||||||
unsigned soimpdlls;
|
|
||||||
|
|
||||||
void processRelocs();
|
void processLoadConf(Reloc *, const Interval *, unsigned);
|
||||||
void processRelocs(PackW32Pe_Reloc *);
|
void processLoadConf(Interval *);
|
||||||
void rebuildRelocs(upx_byte *&);
|
|
||||||
upx_byte *orelocs;
|
|
||||||
unsigned sorelocs;
|
|
||||||
upx_byte *oxrelocs;
|
|
||||||
unsigned soxrelocs;
|
|
||||||
|
|
||||||
void processExports(PackW32Pe_Export *);
|
|
||||||
void processExports(PackW32Pe_Export *,unsigned);
|
|
||||||
void rebuildExports();
|
|
||||||
upx_byte *oexport;
|
|
||||||
unsigned soexport;
|
|
||||||
|
|
||||||
void processResources(PackW32Pe_Resource *);
|
|
||||||
void processResources(PackW32Pe_Resource *, unsigned);
|
|
||||||
void rebuildResources(upx_byte *&);
|
|
||||||
upx_byte *oresources;
|
|
||||||
unsigned soresources;
|
|
||||||
|
|
||||||
void processTls(PackW32Pe_Interval *);
|
|
||||||
void processTls(PackW32Pe_Reloc *,const PackW32Pe_Interval *,unsigned);
|
|
||||||
void rebuildTls();
|
|
||||||
upx_byte *otls;
|
|
||||||
unsigned sotls;
|
|
||||||
|
|
||||||
unsigned stripDebug(unsigned);
|
|
||||||
|
|
||||||
unsigned icondir_offset;
|
|
||||||
int icondir_count;
|
|
||||||
|
|
||||||
bool importbyordinal;
|
|
||||||
bool kernel32ordinal;
|
|
||||||
unsigned tlsindex;
|
|
||||||
unsigned rvamin;
|
|
||||||
unsigned cimports; // rva of preprocessed imports
|
|
||||||
unsigned crelocs; // rva of preprocessed fixups
|
|
||||||
int big_relocs;
|
|
||||||
|
|
||||||
void processLoadConf(PackW32Pe_Reloc *, const PackW32Pe_Interval *, unsigned);
|
|
||||||
void processLoadConf(PackW32Pe_Interval *);
|
|
||||||
upx_byte *oloadconf;
|
upx_byte *oloadconf;
|
||||||
unsigned soloadconf;
|
unsigned soloadconf;
|
||||||
|
|
||||||
bool use_dep_hack;
|
bool use_dep_hack;
|
||||||
bool use_clear_dirty_stack;
|
bool use_clear_dirty_stack;
|
||||||
|
|
||||||
struct pe_header_t
|
|
||||||
{
|
|
||||||
// 0x0
|
|
||||||
char _[4]; // pemagic
|
|
||||||
LE16 cpu;
|
|
||||||
LE16 objects;
|
|
||||||
char __[12]; // timestamp + reserved
|
|
||||||
LE16 opthdrsize;
|
|
||||||
LE16 flags;
|
|
||||||
// optional header
|
|
||||||
char ___[4]; // coffmagic + linkerversion
|
|
||||||
LE32 codesize;
|
|
||||||
// 0x20
|
|
||||||
LE32 datasize;
|
|
||||||
LE32 bsssize;
|
|
||||||
LE32 entry;
|
|
||||||
LE32 codebase;
|
|
||||||
// 0x30
|
|
||||||
LE32 database;
|
|
||||||
// nt specific fields
|
|
||||||
LE32 imagebase;
|
|
||||||
LE32 objectalign;
|
|
||||||
LE32 filealign; // should set to 0x200 ?
|
|
||||||
// 0x40
|
|
||||||
char ____[16]; // versions
|
|
||||||
// 0x50
|
|
||||||
LE32 imagesize;
|
|
||||||
LE32 headersize;
|
|
||||||
LE32 chksum; // should set to 0
|
|
||||||
LE16 subsystem;
|
|
||||||
LE16 dllflags;
|
|
||||||
// 0x60
|
|
||||||
char _____[20]; // stack + heap sizes
|
|
||||||
// 0x74
|
|
||||||
LE32 ddirsentries; // usually 16
|
|
||||||
|
|
||||||
struct ddirs_t
|
|
||||||
{
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct ddirs_t ddirs[16];
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
struct pe_section_t
|
|
||||||
{
|
|
||||||
char name[8];
|
|
||||||
LE32 vsize;
|
|
||||||
LE32 vaddr;
|
|
||||||
LE32 size;
|
|
||||||
LE32 rawdataptr;
|
|
||||||
char _[12];
|
|
||||||
LE32 flags;
|
|
||||||
}
|
|
||||||
__attribute_packed;
|
|
||||||
|
|
||||||
pe_header_t ih, oh;
|
|
||||||
pe_section_t *isection;
|
|
||||||
|
|
||||||
static unsigned virta2objnum (unsigned, pe_section_t *, unsigned);
|
|
||||||
unsigned tryremove (unsigned, unsigned);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEDIR_EXPORT = 0,
|
|
||||||
PEDIR_IMPORT = 1,
|
|
||||||
PEDIR_RESOURCE = 2,
|
|
||||||
PEDIR_EXCEPTION = 3, // Exception table
|
|
||||||
PEDIR_SEC = 4, // Certificate table (file pointer)
|
|
||||||
PEDIR_RELOC = 5,
|
|
||||||
PEDIR_DEBUG = 6,
|
|
||||||
PEDIR_COPYRIGHT = 7, // Architecture-specific data
|
|
||||||
PEDIR_GLOBALPTR = 8, // Global pointer
|
|
||||||
PEDIR_TLS = 9,
|
|
||||||
PEDIR_LOADCONF = 10, // Load Config Table
|
|
||||||
PEDIR_BOUNDIM = 11,
|
|
||||||
PEDIR_IAT = 12,
|
|
||||||
PEDIR_DELAYIMP = 13, // Delay Import Descriptor
|
|
||||||
PEDIR_COMRT = 14 // Com+ Runtime Header
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PEFL_CODE = 0x20,
|
|
||||||
PEFL_DATA = 0x40,
|
|
||||||
PEFL_BSS = 0x80,
|
|
||||||
PEFL_INFO = 0x200,
|
|
||||||
PEFL_EXTRELS = 0x01000000, // extended relocations
|
|
||||||
PEFL_DISCARD = 0x02000000,
|
|
||||||
PEFL_NOCACHE = 0x04000000,
|
|
||||||
PEFL_NOPAGE = 0x08000000,
|
|
||||||
PEFL_SHARED = 0x10000000,
|
|
||||||
PEFL_EXEC = 0x20000000,
|
|
||||||
PEFL_READ = 0x40000000,
|
|
||||||
PEFL_WRITE = 0x80000000
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RELOCS_STRIPPED = 0x0001,
|
|
||||||
EXECUTABLE = 0x0002,
|
|
||||||
LNUM_STRIPPED = 0x0004,
|
|
||||||
LSYMS_STRIPPED = 0x0008,
|
|
||||||
AGGRESSIVE_TRIM = 0x0010,
|
|
||||||
TWO_GIGS_AWARE = 0x0020,
|
|
||||||
FLITTLE_ENDIAN = 0x0080,
|
|
||||||
BITS_32_MACHINE = 0x0100,
|
|
||||||
DEBUG_STRIPPED = 0x0200,
|
|
||||||
REMOVABLE_SWAP = 0x0400,
|
|
||||||
SYSTEM_PROGRAM = 0x1000,
|
|
||||||
DLL_FLAG = 0x2000,
|
|
||||||
FBIG_ENDIAN = 0x8000
|
|
||||||
};
|
|
||||||
|
|
||||||
// predefined resource types
|
|
||||||
enum {
|
|
||||||
RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING,
|
|
||||||
RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE,
|
|
||||||
RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE,
|
|
||||||
RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML,
|
|
||||||
RT_MANIFEST, RT_LAST
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+55
-31
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -32,9 +32,10 @@
|
|||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "lefile.h"
|
#include "lefile.h"
|
||||||
#include "p_wcle.h"
|
#include "p_wcle.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/l_wcle.h"
|
#include "stub/i386-dos32.watcom.le.h"
|
||||||
|
|
||||||
#define LEOF_READ (1<<0)
|
#define LEOF_READ (1<<0)
|
||||||
#define LEOF_WRITE (1<<1)
|
#define LEOF_WRITE (1<<1)
|
||||||
@@ -81,15 +82,22 @@ const int *PackWcle::getFilters() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackWcle::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PackWcle::buildLoader(const Filter *ft)
|
int PackWcle::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||||
addLoader("IDENTSTR,WCLEMAIN,UPX1HEAD,WCLECUTP,+0000000",
|
addLoader("IDENTSTR,WCLEMAIN,UPX1HEAD,WCLECUTP", NULL);
|
||||||
getDecompressor(),
|
|
||||||
"WCLEMAI2",
|
// fake alignment for the start of the decompressor
|
||||||
NULL
|
linker->defineSymbol("WCLECUTP", 0x1000);
|
||||||
);
|
|
||||||
|
addLoader(getDecompressorSections(), "WCLEMAI2", NULL);
|
||||||
if (ft->id)
|
if (ft->id)
|
||||||
{
|
{
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
@@ -110,6 +118,7 @@ int PackWcle::buildLoader(const Filter *ft)
|
|||||||
"WCLEMAI4",
|
"WCLEMAI4",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
freezeLoader();
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +142,20 @@ bool PackWcle::canPack()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||||
|
{
|
||||||
|
if (ft->id == 0)
|
||||||
|
return false;
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
|
||||||
|
linker->defineSymbol("filter_cto", ft->cto);
|
||||||
|
linker->defineSymbol("filter_length",
|
||||||
|
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||||
|
ft->lastcall - ft->calls * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -218,7 +241,7 @@ void PackWcle::encodeObjectTable()
|
|||||||
// object #2: stack
|
// object #2: stack
|
||||||
OOT(1,base_address) = (OOT(0,base_address)
|
OOT(1,base_address) = (OOT(0,base_address)
|
||||||
+OOT(0,virtual_size)+mps-1) & ~(mps-1);
|
+OOT(0,virtual_size)+mps-1) & ~(mps-1);
|
||||||
OOT(1,virtual_size) = mps;
|
OOT(1,virtual_size) = mps + getDecompressorWrkmemSize();
|
||||||
OOT(1,flags) = LEOF_READ|LEOF_HUGE32|LEOF_WRITE;
|
OOT(1,flags) = LEOF_READ|LEOF_HUGE32|LEOF_WRITE;
|
||||||
OOT(1,pagemap_index) = 1;
|
OOT(1,pagemap_index) = 1;
|
||||||
|
|
||||||
@@ -447,7 +470,7 @@ void PackWcle::pack(OutputFile *fo)
|
|||||||
|| ih.module_directives_entries
|
|| ih.module_directives_entries
|
||||||
|| ih.imported_modules_count
|
|| ih.imported_modules_count
|
||||||
|| ih.object_table_entries > 255)
|
|| ih.object_table_entries > 255)
|
||||||
throwCantPack("unexpected value in header");
|
throwCantPack("watcom/le: unexpected value in header");
|
||||||
|
|
||||||
readObjectTable();
|
readObjectTable();
|
||||||
readPageMap();
|
readPageMap();
|
||||||
@@ -496,16 +519,10 @@ void PackWcle::pack(OutputFile *fo)
|
|||||||
neweip = getLoaderSection("WCLEMAIN");
|
neweip = getLoaderSection("WCLEMAIN");
|
||||||
int e_len = getLoaderSectionStart("WCLECUTP");
|
int e_len = getLoaderSectionStart("WCLECUTP");
|
||||||
const unsigned d_len = lsize - e_len;
|
const unsigned d_len = lsize - e_len;
|
||||||
assert(e_len > 0);
|
assert(e_len > 0 && e_len < RESERVED);
|
||||||
|
|
||||||
getLoader();
|
|
||||||
|
|
||||||
memcpy(oimage,getLoader(),e_len);
|
|
||||||
memmove(oimage+e_len,oimage+RESERVED,soimage);
|
memmove(oimage+e_len,oimage+RESERVED,soimage);
|
||||||
soimage = (soimage + e_len);
|
soimage += lsize;
|
||||||
|
|
||||||
memcpy(oimage+soimage,getLoader() + e_len,d_len);
|
|
||||||
soimage += d_len;
|
|
||||||
|
|
||||||
opages = (soimage+mps-1)/mps;
|
opages = (soimage+mps-1)/mps;
|
||||||
oh.bytes_on_last_page = soimage%mps;
|
oh.bytes_on_last_page = soimage%mps;
|
||||||
@@ -523,22 +540,29 @@ void PackWcle::pack(OutputFile *fo)
|
|||||||
ic = (OOT(0,virtual_size) - d_len) &~ 15;
|
ic = (OOT(0,virtual_size) - d_len) &~ 15;
|
||||||
assert(ic > ((ph.u_len + ph.overlap_overhead + 31) &~ 15));
|
assert(ic > ((ph.u_len + ph.overlap_overhead + 31) &~ 15));
|
||||||
|
|
||||||
upx_byte * const p = oimage + soimage - d_len;
|
linker->defineSymbol("WCLECUTP", ic);
|
||||||
patch_le32(p,d_len,"JMPO",ih.init_eip_offset+text_vaddr-(ic+d_len));
|
|
||||||
patch_le32(p,d_len,"ESP0",ih.init_esp_offset+IOT(ih.init_ss_object-1,my_base_address));
|
|
||||||
if (patchFilter32(p, d_len, &ft) && text_vaddr)
|
|
||||||
patch_le32(p, d_len, "TEXV", text_vaddr);
|
|
||||||
patch_le32(p,d_len,"RELO",mps*pages);
|
|
||||||
|
|
||||||
patchPackHeader(oimage,e_len);
|
linker->defineSymbol("original_entry", ih.init_eip_offset + text_vaddr);
|
||||||
|
linker->defineSymbol("original_stack", ih.init_esp_offset +
|
||||||
|
IOT(ih.init_ss_object - 1, my_base_address));
|
||||||
|
linker->defineSymbol("start_of_relocs", mps*pages);
|
||||||
|
defineFilterSymbols(linker, &ft);
|
||||||
|
linker->defineSymbol("filter_buffer_start", text_vaddr);
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
|
||||||
unsigned jpos = find_le32(oimage,e_len,get_le32("JMPD"));
|
unsigned jpos = (((ph.c_len + 3) &~ 3) + d_len + 3) / 4;
|
||||||
patch_le32(oimage,e_len,"JMPD",ic-jpos-4);
|
linker->defineSymbol("words_to_copy", jpos);
|
||||||
|
linker->defineSymbol("copy_dest", ((ic + d_len + 3) &~ 3) - 4);
|
||||||
|
linker->defineSymbol("copy_source", e_len + jpos * 4 - 4);
|
||||||
|
|
||||||
jpos = (((ph.c_len+3)&~3) + d_len+3)/4;
|
linker->relocate();
|
||||||
patch_le32(oimage,e_len,"ECX0",jpos);
|
|
||||||
patch_le32(oimage,e_len,"EDI0",((ic+d_len+3)&~3)-4);
|
MemBuffer loader(lsize);
|
||||||
patch_le32(oimage,e_len,"ESI0",e_len+jpos*4-4);
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
|
memcpy(oimage, loader, e_len);
|
||||||
|
memcpy(oimage + soimage - d_len, loader + e_len, d_len);
|
||||||
|
|
||||||
writeFile(fo, opt->watcom_le.le);
|
writeFile(fo, opt->watcom_le.le);
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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
|
||||||
@@ -55,6 +55,7 @@ protected:
|
|||||||
virtual void handleStub(OutputFile *fo);
|
virtual void handleStub(OutputFile *fo);
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
virtual void readObjectTable();
|
virtual void readObjectTable();
|
||||||
virtual void encodeObjectTable();
|
virtual void encodeObjectTable();
|
||||||
|
|||||||
+142
-307
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
Packer::Packer(InputFile *f) :
|
Packer::Packer(InputFile *f) :
|
||||||
fi(f), file_size(-1), ph_format(-1), ph_version(-1),
|
fi(f), file_size(-1), ph_format(-1), ph_version(-1),
|
||||||
uip(NULL), ui_pass(0), ui_total_passes(0), linker(NULL),
|
uip(NULL), linker(NULL),
|
||||||
last_patch(NULL), last_patch_len(0), last_patch_off(0)
|
last_patch(NULL), last_patch_len(0), last_patch_off(0)
|
||||||
{
|
{
|
||||||
file_size = f->st.st_size;
|
file_size = f->st.st_size;
|
||||||
@@ -138,20 +138,29 @@ bool Packer::testUnpackFormat(int format) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ph_skipVerify(const PackHeader &ph)
|
||||||
|
{
|
||||||
|
if (ph.method == M_LZMA)
|
||||||
|
return false;
|
||||||
|
if (ph.level > 1)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress
|
// compress - wrap call to low-level upx_compress()
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool Packer::compress(upx_bytep in, upx_bytep out,
|
bool Packer::compress(upx_bytep in, upx_bytep out,
|
||||||
unsigned max_offset, unsigned max_match)
|
const upx_compress_config_t *cconf_parm)
|
||||||
{
|
{
|
||||||
#if defined(UNUPX)
|
|
||||||
throwInternalError("compression failed");
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
ph.c_len = 0;
|
ph.c_len = 0;
|
||||||
assert(ph.level >= 1); assert(ph.level <= 10);
|
assert(ph.level >= 1); assert(ph.level <= 10);
|
||||||
|
|
||||||
|
// Avoid too many progress bar updates. 64 is s->bar_len in ui.cpp.
|
||||||
|
unsigned step = (ph.u_len < 64*1024) ? 0 : ph.u_len / 64;
|
||||||
|
|
||||||
// save current checksums
|
// save current checksums
|
||||||
ph.saved_u_adler = ph.u_adler;
|
ph.saved_u_adler = ph.u_adler;
|
||||||
ph.saved_c_adler = ph.c_adler;
|
ph.saved_c_adler = ph.c_adler;
|
||||||
@@ -159,49 +168,38 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
|||||||
ph.u_adler = upx_adler32(in, ph.u_len, ph.u_adler);
|
ph.u_adler = upx_adler32(in, ph.u_len, ph.u_adler);
|
||||||
|
|
||||||
// set compression paramters
|
// set compression paramters
|
||||||
upx_compress_config_t conf;
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
if (cconf_parm)
|
||||||
// arguments
|
cconf = *cconf_parm;
|
||||||
if (max_offset != 0)
|
// cconf options
|
||||||
conf.max_offset = max_offset;
|
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||||
if (max_match != 0)
|
{
|
||||||
conf.max_match = max_match;
|
if (opt->crp.crp_ucl.c_flags != -1)
|
||||||
// options
|
cconf.conf_ucl.c_flags = opt->crp.crp_ucl.c_flags;
|
||||||
if (opt->crp.c_flags != -1)
|
if (opt->crp.crp_ucl.p_level != -1)
|
||||||
conf.c_flags = opt->crp.c_flags;
|
cconf.conf_ucl.p_level = opt->crp.crp_ucl.p_level;
|
||||||
#if 0
|
if (opt->crp.crp_ucl.h_level != -1)
|
||||||
else
|
cconf.conf_ucl.h_level = opt->crp.crp_ucl.h_level;
|
||||||
// this is based on experimentation
|
if (opt->crp.crp_ucl.max_offset != UINT_MAX && opt->crp.crp_ucl.max_offset < cconf.conf_ucl.max_offset)
|
||||||
conf.c_flags = (ph.level >= 7) ? 0 : 1 | 2;
|
cconf.conf_ucl.max_offset = opt->crp.crp_ucl.max_offset;
|
||||||
#endif
|
if (opt->crp.crp_ucl.max_match != UINT_MAX && opt->crp.crp_ucl.max_match < cconf.conf_ucl.max_match)
|
||||||
if (opt->crp.p_level != -1)
|
cconf.conf_ucl.max_match = opt->crp.crp_ucl.max_match;
|
||||||
conf.p_level = opt->crp.p_level;
|
|
||||||
if (opt->crp.h_level != -1)
|
|
||||||
conf.h_level = opt->crp.h_level;
|
|
||||||
if (opt->crp.max_offset != UPX_UINT_MAX && opt->crp.max_offset < conf.max_offset)
|
|
||||||
conf.max_offset = opt->crp.max_offset;
|
|
||||||
if (opt->crp.max_match != UPX_UINT_MAX && opt->crp.max_match < conf.max_match)
|
|
||||||
conf.max_match = opt->crp.max_match;
|
|
||||||
|
|
||||||
// Avoid too many progress bar updates. 64 is s->bar_len in ui.cpp.
|
|
||||||
unsigned step = (ph.u_len < 64*1024) ? 0 : ph.u_len / 64;
|
|
||||||
#if defined(WITH_NRV)
|
#if defined(WITH_NRV)
|
||||||
if (ph.level >= 7 || (ph.level >= 4 && ph.u_len >= 512*1024))
|
if (ph.level >= 7 || (ph.level >= 4 && ph.u_len >= 512*1024))
|
||||||
step = 0;
|
step = 0;
|
||||||
#endif
|
#endif
|
||||||
if (ui_pass >= 0)
|
}
|
||||||
ui_pass++;
|
if (uip->ui_pass >= 0)
|
||||||
uip->startCallback(ph.u_len, step, ui_pass, ui_total_passes);
|
uip->ui_pass++;
|
||||||
|
uip->startCallback(ph.u_len, step, uip->ui_pass, uip->ui_total_passes);
|
||||||
uip->firstCallback();
|
uip->firstCallback();
|
||||||
|
|
||||||
//OutputFile::dump("data.raw", in, ph.u_len);
|
//OutputFile::dump("data.raw", in, ph.u_len);
|
||||||
|
|
||||||
// compress
|
// compress
|
||||||
unsigned result[16];
|
|
||||||
memset(result, 0, sizeof(result));
|
|
||||||
int r = upx_compress(in, ph.u_len, out, &ph.c_len,
|
int r = upx_compress(in, ph.u_len, out, &ph.c_len,
|
||||||
uip->getCallback(),
|
uip->getCallback(),
|
||||||
ph.method, ph.level, &conf, result);
|
ph.method, ph.level, &cconf, &ph.compress_result);
|
||||||
|
|
||||||
//uip->finalCallback(ph.u_len, ph.c_len);
|
//uip->finalCallback(ph.u_len, ph.c_len);
|
||||||
uip->endCallback();
|
uip->endCallback();
|
||||||
@@ -211,16 +209,23 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
|||||||
if (r != UPX_E_OK)
|
if (r != UPX_E_OK)
|
||||||
throwInternalError("compression failed");
|
throwInternalError("compression failed");
|
||||||
|
|
||||||
//ph.min_offset_found = result[0];
|
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||||
ph.max_offset_found = result[1];
|
{
|
||||||
//ph.min_match_found = result[2];
|
ucl_uint *res = ph.compress_result.result_ucl.result;
|
||||||
ph.max_match_found = result[3];
|
//ph.min_offset_found = res[0];
|
||||||
//ph.min_run_found = result[4];
|
ph.max_offset_found = res[1];
|
||||||
ph.max_run_found = result[5];
|
//ph.min_match_found = res[2];
|
||||||
ph.first_offset_found = result[6];
|
ph.max_match_found = res[3];
|
||||||
//ph.same_match_offsets_found = result[7];
|
//ph.min_run_found = res[4];
|
||||||
assert(max_offset == 0 || max_offset >= ph.max_offset_found);
|
ph.max_run_found = res[5];
|
||||||
assert(max_match == 0 || max_match >= ph.max_match_found);
|
ph.first_offset_found = res[6];
|
||||||
|
//ph.same_match_offsets_found = res[7];
|
||||||
|
if (cconf_parm)
|
||||||
|
{
|
||||||
|
assert(cconf.conf_ucl.max_offset == 0 || cconf.conf_ucl.max_offset >= ph.max_offset_found);
|
||||||
|
assert(cconf.conf_ucl.max_match == 0 || cconf.conf_ucl.max_match >= ph.max_match_found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//printf("\nPacker::compress: %d/%d: %7d -> %7d\n", ph.method, ph.level, ph.u_len, ph.c_len);
|
//printf("\nPacker::compress: %d/%d: %7d -> %7d\n", ph.method, ph.level, ph.u_len, ph.c_len);
|
||||||
if (!checkCompressionRatio(ph.u_len, ph.c_len))
|
if (!checkCompressionRatio(ph.u_len, ph.c_len))
|
||||||
@@ -232,11 +237,11 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
|||||||
// update checksum of compressed data
|
// update checksum of compressed data
|
||||||
ph.c_adler = upx_adler32(out, ph.c_len, ph.c_adler);
|
ph.c_adler = upx_adler32(out, ph.c_len, ph.c_adler);
|
||||||
// Decompress and verify. Skip this when using the fastest level.
|
// Decompress and verify. Skip this when using the fastest level.
|
||||||
if (ph.level > 1)
|
if (!ph_skipVerify(ph))
|
||||||
{
|
{
|
||||||
// decompress
|
// decompress
|
||||||
unsigned new_len = ph.u_len;
|
unsigned new_len = ph.u_len;
|
||||||
r = upx_decompress(out, ph.c_len, in, &new_len, ph.method);
|
r = upx_decompress(out, ph.c_len, in, &new_len, ph.method, &ph.compress_result);
|
||||||
//printf("%d %d: %d %d %d\n", ph.method, r, ph.c_len, ph.u_len, new_len);
|
//printf("%d %d: %d %d %d\n", ph.method, r, ph.c_len, ph.u_len, new_len);
|
||||||
if (r != UPX_E_OK)
|
if (r != UPX_E_OK)
|
||||||
throwInternalError("decompression failed");
|
throwInternalError("decompression failed");
|
||||||
@@ -248,10 +253,18 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
|||||||
throwInternalError("decompression failed (checksum error)");
|
throwInternalError("decompression failed (checksum error)");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
#endif /* UNUPX */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
bool Packer::compress(upx_bytep in, upx_bytep out,
|
||||||
|
const upx_compress_config_t *cconf)
|
||||||
|
{
|
||||||
|
return ph_compress(ph, in, out, cconf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool Packer::checkCompressionRatio(unsigned u_len, unsigned c_len) const
|
bool Packer::checkCompressionRatio(unsigned u_len, unsigned c_len) const
|
||||||
{
|
{
|
||||||
assert((int)u_len > 0);
|
assert((int)u_len > 0);
|
||||||
@@ -294,7 +307,7 @@ bool Packer::checkFinalCompressionRatio(const OutputFile *fo) const
|
|||||||
// decompress
|
// decompress
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void Packer::decompress(const upx_bytep in, upx_bytep out,
|
void ph_decompress(PackHeader &ph, const upx_bytep in, upx_bytep out,
|
||||||
bool verify_checksum, Filter *ft)
|
bool verify_checksum, Filter *ft)
|
||||||
{
|
{
|
||||||
unsigned adler;
|
unsigned adler;
|
||||||
@@ -309,7 +322,7 @@ void Packer::decompress(const upx_bytep in, upx_bytep out,
|
|||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
unsigned new_len = ph.u_len;
|
unsigned new_len = ph.u_len;
|
||||||
int r = upx_decompress(in, ph.c_len, out, &new_len, ph.method);
|
int r = upx_decompress(in, ph.c_len, out, &new_len, ph.method, &ph.compress_result);
|
||||||
if (r != UPX_E_OK || new_len != ph.u_len)
|
if (r != UPX_E_OK || new_len != ph.u_len)
|
||||||
throwCompressedDataViolation();
|
throwCompressedDataViolation();
|
||||||
|
|
||||||
@@ -326,35 +339,47 @@ void Packer::decompress(const upx_bytep in, upx_bytep out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Packer::decompress(const upx_bytep in, upx_bytep out,
|
||||||
|
bool verify_checksum, Filter *ft)
|
||||||
|
{
|
||||||
|
ph_decompress(ph, in, out, verify_checksum, ft);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// overlapping decompression
|
// overlapping decompression
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool Packer::testOverlappingDecompression(const upx_bytep buf,
|
bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf,
|
||||||
unsigned overlap_overhead) const
|
unsigned overlap_overhead)
|
||||||
{
|
{
|
||||||
#if defined(UNUPX)
|
|
||||||
UNUSED(buf);
|
|
||||||
UNUSED(overlap_overhead);
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
if (ph.c_len >= ph.u_len)
|
if (ph.c_len >= ph.u_len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert((int)overlap_overhead >= 0);
|
assert((int)overlap_overhead >= 0);
|
||||||
|
|
||||||
// Because upx_test_overlap() does not use the asm_fast decompressor
|
// Because upx_test_overlap() does not use the asm_fast decompressor
|
||||||
// we must account for extra 3 bytes that asm_fast does use,
|
// we must account for extra 3 bytes that asm_fast does use,
|
||||||
// or else we may fail at runtime decompression.
|
// or else we may fail at runtime decompression.
|
||||||
if (overlap_overhead <= 4 + 3) // don't waste time here
|
unsigned extra = 0;
|
||||||
|
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||||
|
extra = 3;
|
||||||
|
if (overlap_overhead <= 4 + extra) // don't waste time here
|
||||||
return false;
|
return false;
|
||||||
overlap_overhead -= 3;
|
overlap_overhead -= extra;
|
||||||
|
|
||||||
unsigned src_off = ph.u_len + overlap_overhead - ph.c_len;
|
unsigned src_off = ph.u_len + overlap_overhead - ph.c_len;
|
||||||
unsigned new_len = ph.u_len;
|
unsigned new_len = ph.u_len;
|
||||||
int r = upx_test_overlap(buf - src_off, src_off,
|
int r = upx_test_overlap(buf - src_off, src_off,
|
||||||
ph.c_len, &new_len, ph.method);
|
ph.c_len, &new_len, ph.method, &ph.compress_result);
|
||||||
return (r == UPX_E_OK && new_len == ph.u_len);
|
return (r == UPX_E_OK && new_len == ph.u_len);
|
||||||
#endif /* UNUPX */
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Packer::testOverlappingDecompression(const upx_bytep buf,
|
||||||
|
unsigned overlap_overhead) const
|
||||||
|
{
|
||||||
|
return ph_testOverlappingDecompression(ph, buf, overlap_overhead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -362,7 +387,6 @@ void Packer::verifyOverlappingDecompression(Filter *ft)
|
|||||||
{
|
{
|
||||||
assert(ph.c_len < ph.u_len);
|
assert(ph.c_len < ph.u_len);
|
||||||
assert((int)ph.overlap_overhead > 0);
|
assert((int)ph.overlap_overhead > 0);
|
||||||
#if 1 && !defined(UNUPX)
|
|
||||||
// Idea:
|
// Idea:
|
||||||
// obuf[] was allocated with MemBuffer::allocForCompression(), and
|
// obuf[] was allocated with MemBuffer::allocForCompression(), and
|
||||||
// its contents are no longer needed, i.e. the compressed data
|
// its contents are no longer needed, i.e. the compressed data
|
||||||
@@ -378,7 +402,7 @@ void Packer::verifyOverlappingDecompression(Filter *ft)
|
|||||||
// See also:
|
// See also:
|
||||||
// Filter::verifyUnfilter()
|
// Filter::verifyUnfilter()
|
||||||
|
|
||||||
if (ph.level == 1)
|
if (ph_skipVerify(ph))
|
||||||
return;
|
return;
|
||||||
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
||||||
if (offset + ph.c_len > obuf.getSize())
|
if (offset + ph.c_len > obuf.getSize())
|
||||||
@@ -386,7 +410,6 @@ void Packer::verifyOverlappingDecompression(Filter *ft)
|
|||||||
memmove(obuf + offset, obuf, ph.c_len);
|
memmove(obuf + offset, obuf, ph.c_len);
|
||||||
decompress(obuf + offset, obuf, true, ft);
|
decompress(obuf + offset, obuf, true, ft);
|
||||||
obuf.checkState();
|
obuf.checkState();
|
||||||
#endif /* !UNUPX */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -404,10 +427,6 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
|||||||
unsigned range,
|
unsigned range,
|
||||||
unsigned upper_limit) const
|
unsigned upper_limit) const
|
||||||
{
|
{
|
||||||
#if defined(UNUPX)
|
|
||||||
throwInternalError("not implemented");
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
assert((int) range >= 0);
|
assert((int) range >= 0);
|
||||||
|
|
||||||
// prepare to deal with very pessimistic values
|
// prepare to deal with very pessimistic values
|
||||||
@@ -424,7 +443,9 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
|||||||
assert(m >= low); assert(m <= high);
|
assert(m >= low); assert(m <= high);
|
||||||
assert(m < overhead || overhead == 0);
|
assert(m < overhead || overhead == 0);
|
||||||
nr++;
|
nr++;
|
||||||
if (testOverlappingDecompression(buf, m))
|
bool success = testOverlappingDecompression(buf, m);
|
||||||
|
//printf("testOverlapOverhead: %d %d -> %d\n", nr, m, (int)success);
|
||||||
|
if (success)
|
||||||
{
|
{
|
||||||
overhead = m;
|
overhead = m;
|
||||||
// Succeed early if m lies in [low .. low+range-1], i.e. if
|
// Succeed early if m lies in [low .. low+range-1], i.e. if
|
||||||
@@ -445,7 +466,6 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
|||||||
|
|
||||||
UNUSED(nr);
|
UNUSED(nr);
|
||||||
return overhead;
|
return overhead;
|
||||||
#endif /* UNUPX */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -657,7 +677,7 @@ bool Packer::readPackHeader(int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Packer::checkAlreadyPacked(void *b, int blen)
|
void Packer::checkAlreadyPacked(const void *b, int blen)
|
||||||
{
|
{
|
||||||
int boff = find_le32(b, blen, UPX_MAGIC_LE32);
|
int boff = find_le32(b, blen, UPX_MAGIC_LE32);
|
||||||
if (boff < 0)
|
if (boff < 0)
|
||||||
@@ -808,38 +828,6 @@ int Packer::patch_le32(void *b, int blen, const void *old, unsigned new_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// patch version into stub/ident_n.ash
|
|
||||||
int Packer::patchVersion(void *b, int blen)
|
|
||||||
{
|
|
||||||
int boff = find(b, blen, "$Id: UPX UPXV ", 14);
|
|
||||||
checkPatch(b, blen, boff, 14);
|
|
||||||
|
|
||||||
unsigned char *p = (unsigned char *)b + boff + 9;
|
|
||||||
if (opt->debug.fake_stub_version[0])
|
|
||||||
memcpy(p, opt->debug.fake_stub_version, 4);
|
|
||||||
else
|
|
||||||
memcpy(p, UPX_VERSION_STRING4, 4);
|
|
||||||
|
|
||||||
return boff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// patch year into stub/ident_[ns].ash
|
|
||||||
int Packer::patchVersionYear(void *b, int blen)
|
|
||||||
{
|
|
||||||
int boff = find(b, blen, " 1996-UPXY ", 11);
|
|
||||||
checkPatch(b, blen, boff, 11);
|
|
||||||
|
|
||||||
unsigned char *p = (unsigned char *)b + boff + 6;
|
|
||||||
if (opt->debug.fake_stub_year[0])
|
|
||||||
memcpy(p, opt->debug.fake_stub_year, 4);
|
|
||||||
else
|
|
||||||
memcpy(p, UPX_VERSION_YEAR, 4);
|
|
||||||
|
|
||||||
return boff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// relocation util
|
// relocation util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -848,9 +836,6 @@ upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum,
|
|||||||
upx_byte *out, upx_byte *image,
|
upx_byte *out, upx_byte *image,
|
||||||
int bswap, int *big)
|
int bswap, int *big)
|
||||||
{
|
{
|
||||||
#if defined(UNUPX)
|
|
||||||
return out;
|
|
||||||
#else
|
|
||||||
*big = 0;
|
*big = 0;
|
||||||
if (relocnum == 0)
|
if (relocnum == 0)
|
||||||
return out;
|
return out;
|
||||||
@@ -890,7 +875,6 @@ upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum,
|
|||||||
}
|
}
|
||||||
*fix++ = 0;
|
*fix++ = 0;
|
||||||
return fix;
|
return fix;
|
||||||
#endif /* UNUPX */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -937,58 +921,32 @@ unsigned Packer::unoptimizeReloc32(upx_byte **in, upx_byte *image,
|
|||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compression method util
|
// loader util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool Packer::isValidCompressionMethod(int method)
|
void Packer::freezeLoader()
|
||||||
{
|
{
|
||||||
return (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16);
|
linker->freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *Packer::getDefaultCompressionMethods_8(int method, int level, int small) const
|
upx_byte *Packer::getLoader() const
|
||||||
{
|
{
|
||||||
static const int m_nrv2b[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, -1 };
|
int size = -1;
|
||||||
static const int m_nrv2d[] = { M_NRV2D_8, M_NRV2B_8, M_NRV2E_8, -1 };
|
upx_byte *oloader = linker->getLoader(&size);
|
||||||
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_NRV2D_8, -1 };
|
if (oloader == NULL || size <= 0)
|
||||||
static const int m_cl1b[] = { M_CL1B_8, -1 };
|
throwBadLoader();
|
||||||
|
return oloader;
|
||||||
if (small < 0)
|
|
||||||
small = file_size <= 512*1024;
|
|
||||||
if (M_IS_NRV2B(method))
|
|
||||||
return m_nrv2b;
|
|
||||||
if (M_IS_NRV2D(method))
|
|
||||||
return m_nrv2d;
|
|
||||||
if (M_IS_NRV2E(method))
|
|
||||||
return m_nrv2e;
|
|
||||||
if (M_IS_CL1B(method))
|
|
||||||
return m_cl1b;
|
|
||||||
if (level == 1 || small)
|
|
||||||
return m_nrv2b;
|
|
||||||
return m_nrv2e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int small) const
|
int Packer::getLoaderSize() const
|
||||||
{
|
{
|
||||||
static const int m_nrv2b[] = { M_NRV2B_LE32, M_NRV2D_LE32, M_NRV2E_LE32, -1 };
|
int size = -1;
|
||||||
static const int m_nrv2d[] = { M_NRV2D_LE32, M_NRV2B_LE32, M_NRV2E_LE32, -1 };
|
upx_byte *oloader = linker->getLoader(&size);
|
||||||
static const int m_nrv2e[] = { M_NRV2E_LE32, M_NRV2B_LE32, M_NRV2D_LE32, -1 };
|
if (oloader == NULL || size <= 0)
|
||||||
static const int m_cl1b[] = { M_CL1B_LE32, -1 };
|
throwBadLoader();
|
||||||
|
return size;
|
||||||
if (small < 0)
|
|
||||||
small = file_size <= 512*1024;
|
|
||||||
if (M_IS_NRV2B(method))
|
|
||||||
return m_nrv2b;
|
|
||||||
if (M_IS_NRV2D(method))
|
|
||||||
return m_nrv2d;
|
|
||||||
if (M_IS_NRV2E(method))
|
|
||||||
return m_nrv2e;
|
|
||||||
if (M_IS_CL1B(method))
|
|
||||||
return m_cl1b;
|
|
||||||
if (level == 1 || small)
|
|
||||||
return m_nrv2b;
|
|
||||||
return m_nrv2e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -996,7 +954,7 @@ const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int
|
|||||||
// loader util
|
// loader util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
char const *Packer::getIdentstr(unsigned *size, int small)
|
static const char *getIdentstr(unsigned *size, int small)
|
||||||
{
|
{
|
||||||
static char identbig[] =
|
static char identbig[] =
|
||||||
"\n\0"
|
"\n\0"
|
||||||
@@ -1055,28 +1013,16 @@ char const *Packer::getIdentstr(unsigned *size, int small)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packer::createLinker(const void *pdata, int plen, int pinfo)
|
|
||||||
{
|
|
||||||
if (getFormat() < 128)
|
|
||||||
linker = new Linker(pdata, plen, pinfo); // little endian
|
|
||||||
else
|
|
||||||
linker = new BeLinker(pdata, plen, pinfo); // big endian
|
|
||||||
}
|
|
||||||
|
|
||||||
void Packer::initLoader(const void *pdata, int plen, int pinfo, int small)
|
void Packer::initLoader(const void *pdata, int plen, int small)
|
||||||
{
|
{
|
||||||
if (pinfo < 0)
|
delete linker;
|
||||||
{
|
linker = newLinker();
|
||||||
pinfo = get_le16((const unsigned char *)pdata + plen - 2);
|
linker->init(pdata, plen);
|
||||||
pinfo = (pinfo + 3) &~ 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete linker; linker = NULL;
|
|
||||||
createLinker(pdata, plen, pinfo);
|
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
char const * const ident = getIdentstr(&size, small);
|
char const * const ident = getIdentstr(&size, small);
|
||||||
linker->addSection("IDENTSTR", ident, size);
|
linker->addSection("IDENTSTR", ident, size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1088,7 +1034,7 @@ void __acc_cdecl_va Packer::addLoader(const char *s, ...)
|
|||||||
while (s != NULL)
|
while (s != NULL)
|
||||||
{
|
{
|
||||||
if (*s)
|
if (*s)
|
||||||
linker->addSection(s);
|
linker->addLoader(s);
|
||||||
s = va_arg(ap, const char *);
|
s = va_arg(ap, const char *);
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@@ -1120,124 +1066,6 @@ int Packer::getLoaderSectionStart(const char *name, int *slen) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const upx_byte *Packer::getLoader() const
|
|
||||||
{
|
|
||||||
int size = -1;
|
|
||||||
const char *oloader = linker->getLoader(&size);
|
|
||||||
if (oloader == NULL || size <= 0)
|
|
||||||
throwBadLoader();
|
|
||||||
return (const upx_byte *) oloader;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Packer::getLoaderSize() const
|
|
||||||
{
|
|
||||||
int size = -1;
|
|
||||||
const char *oloader = linker->getLoader(&size);
|
|
||||||
if (oloader == NULL || size <= 0)
|
|
||||||
throwBadLoader();
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *Packer::getDecompressor() const
|
|
||||||
{
|
|
||||||
static const char nrv2b_le32_small[] =
|
|
||||||
"N2BSMA10,N2BDEC10,N2BSMA20,N2BDEC20,N2BSMA30,"
|
|
||||||
"N2BDEC30,N2BSMA40,N2BSMA50,N2BDEC50,N2BSMA60,"
|
|
||||||
"N2BDEC60";
|
|
||||||
static const char nrv2b_le32_fast[] =
|
|
||||||
"N2BFAS10,+80CXXXX,N2BFAS11,N2BDEC10,N2BFAS20,"
|
|
||||||
"N2BDEC20,N2BFAS30,N2BDEC30,N2BFAS40,N2BFAS50,"
|
|
||||||
"N2BDEC50,N2BFAS60,+40CXXXX,N2BFAS61,N2BDEC60";
|
|
||||||
static const char nrv2d_le32_small[] =
|
|
||||||
"N2DSMA10,N2DDEC10,N2DSMA20,N2DDEC20,N2DSMA30,"
|
|
||||||
"N2DDEC30,N2DSMA40,N2DSMA50,N2DDEC50,N2DSMA60,"
|
|
||||||
"N2DDEC60";
|
|
||||||
static const char nrv2d_le32_fast[] =
|
|
||||||
"N2DFAS10,+80CXXXX,N2DFAS11,N2DDEC10,N2DFAS20,"
|
|
||||||
"N2DDEC20,N2DFAS30,N2DDEC30,N2DFAS40,N2DFAS50,"
|
|
||||||
"N2DDEC50,N2DFAS60,+40CXXXX,N2DFAS61,N2DDEC60";
|
|
||||||
static const char nrv2e_le32_small[] =
|
|
||||||
"N2ESMA10,N2EDEC10,N2ESMA20,N2EDEC20,N2ESMA30,"
|
|
||||||
"N2EDEC30,N2ESMA40,N2ESMA50,N2EDEC50,N2ESMA60,"
|
|
||||||
"N2EDEC60";
|
|
||||||
static const char nrv2e_le32_fast[] =
|
|
||||||
"N2EFAS10,+80CXXXX,N2EFAS11,N2EDEC10,N2EFAS20,"
|
|
||||||
"N2EDEC20,N2EFAS30,N2EDEC30,N2EFAS40,N2EFAS50,"
|
|
||||||
"N2EDEC50,N2EFAS60,+40CXXXX,N2EFAS61,N2EDEC60";
|
|
||||||
static const char cl1b_le32_small[] =
|
|
||||||
"CL1ENTER,CL1SMA10,CL1RLOAD,"
|
|
||||||
"CL1WID01,CL1SMA1B,"
|
|
||||||
"CL1WID02,CL1SMA1B,"
|
|
||||||
"CL1WID03,CL1SMA1B,"
|
|
||||||
"CL1WID04,CL1SMA1B,"
|
|
||||||
"CL1WID05,CL1SMA1B,"
|
|
||||||
"CL1WID06,CL1SMA1B,"
|
|
||||||
"CL1WID07,CL1SMA1B,"
|
|
||||||
"CL1WID08,CL1SMA1B,"
|
|
||||||
"CL1WID09,CL1SMA1B,"
|
|
||||||
"CL1WID10,"
|
|
||||||
"CL1START,"
|
|
||||||
"CL1TOP00,CL1SMA1B,"
|
|
||||||
"CL1TOP01,CL1SMA1B,"
|
|
||||||
"CL1TOP02,CL1SMA1B,"
|
|
||||||
"CL1TOP03,CL1SMA1B,"
|
|
||||||
"CL1TOP04,CL1SMA1B,"
|
|
||||||
"CL1TOP05,CL1SMA1B,"
|
|
||||||
"CL1TOP06,CL1SMA1B,"
|
|
||||||
"CL1TOP07,CL1SMA1B,"
|
|
||||||
"CL1OFF01,CL1SMA1B,"
|
|
||||||
"CL1OFF02,CL1SMA1B,"
|
|
||||||
"CL1OFF03,CL1SMA1B,"
|
|
||||||
"CL1OFF04,"
|
|
||||||
"CL1LEN00,CL1SMA1B,"
|
|
||||||
"CL1LEN01,CL1SMA1B,"
|
|
||||||
"CL1LEN02,"
|
|
||||||
"CL1COPY0";
|
|
||||||
static const char cl1b_le32_fast[] =
|
|
||||||
"CL1ENTER," "CL1RLOAD,"
|
|
||||||
"CL1WID01,CL1FAS1B,"
|
|
||||||
"CL1WID02,CL1FAS1B,"
|
|
||||||
"CL1WID03,CL1FAS1B,"
|
|
||||||
"CL1WID04,CL1FAS1B,"
|
|
||||||
"CL1WID05,CL1FAS1B,"
|
|
||||||
"CL1WID06,CL1FAS1B,"
|
|
||||||
"CL1WID07,CL1FAS1B,"
|
|
||||||
"CL1WID08,CL1FAS1B,"
|
|
||||||
"CL1WID09,CL1FAS1B,"
|
|
||||||
"CL1WID10,"
|
|
||||||
"CL1START,"
|
|
||||||
"CL1TOP00,CL1FAS1B,"
|
|
||||||
"CL1TOP01,CL1FAS1B,"
|
|
||||||
"CL1TOP02,CL1FAS1B,"
|
|
||||||
"CL1TOP03,CL1FAS1B,"
|
|
||||||
"CL1TOP04,CL1FAS1B,"
|
|
||||||
"CL1TOP05,CL1FAS1B,"
|
|
||||||
"CL1TOP06,CL1FAS1B,"
|
|
||||||
"CL1TOP07,CL1FAS1B,"
|
|
||||||
"CL1OFF01,CL1FAS1B,"
|
|
||||||
"CL1OFF02,CL1FAS1B,"
|
|
||||||
"CL1OFF03,CL1FAS1B,"
|
|
||||||
"CL1OFF04,"
|
|
||||||
"CL1LEN00,CL1FAS1B,"
|
|
||||||
"CL1LEN01,CL1FAS1B,"
|
|
||||||
"CL1LEN02,"
|
|
||||||
"CL1COPY0";
|
|
||||||
|
|
||||||
if (ph.method == M_NRV2B_LE32)
|
|
||||||
return opt->small ? nrv2b_le32_small : nrv2b_le32_fast;
|
|
||||||
if (ph.method == M_NRV2D_LE32)
|
|
||||||
return opt->small ? nrv2d_le32_small : nrv2d_le32_fast;
|
|
||||||
if (ph.method == M_NRV2E_LE32)
|
|
||||||
return opt->small ? nrv2e_le32_small : nrv2e_le32_fast;
|
|
||||||
if (ph.method == M_CL1B_LE32)
|
|
||||||
return opt->small ? cl1b_le32_small : cl1b_le32_fast;
|
|
||||||
throwInternalError("bad decompressor");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Try compression with several methods and filters, choose the best
|
// Try compression with several methods and filters, choose the best
|
||||||
/ or first working one. Needs buildLoader().
|
/ or first working one. Needs buildLoader().
|
||||||
@@ -1266,7 +1094,7 @@ const char *Packer::getDecompressor() const
|
|||||||
// executable formats.
|
// executable formats.
|
||||||
//
|
//
|
||||||
// It will replace the tryFilters() / compress() call sequence.
|
// It will replace the tryFilters() / compress() call sequence.
|
||||||
|
//
|
||||||
// 2006-02-15: hdr_buf and hdr_u_len are default empty input "header" array
|
// 2006-02-15: hdr_buf and hdr_u_len are default empty input "header" array
|
||||||
// to fix a 2-pass problem with Elf headers. As of today there can be
|
// to fix a 2-pass problem with Elf headers. As of today there can be
|
||||||
// only one decompression method per executable output file, and that method
|
// only one decompression method per executable output file, and that method
|
||||||
@@ -1288,7 +1116,7 @@ const char *Packer::getDecompressor() const
|
|||||||
void Packer::compressWithFilters(Filter *parm_ft,
|
void Packer::compressWithFilters(Filter *parm_ft,
|
||||||
const unsigned overlap_range,
|
const unsigned overlap_range,
|
||||||
int strategy, const int *parm_filters,
|
int strategy, const int *parm_filters,
|
||||||
unsigned max_offset, unsigned max_match,
|
const upx_compress_config_t *cconf,
|
||||||
unsigned filter_off, unsigned compress_buf_off,
|
unsigned filter_off, unsigned compress_buf_off,
|
||||||
unsigned char *hdr_buf,
|
unsigned char *hdr_buf,
|
||||||
unsigned hdr_u_len)
|
unsigned hdr_u_len)
|
||||||
@@ -1373,25 +1201,29 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||||||
filters[nfilters] = -1;
|
filters[nfilters] = -1;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
int tmp_methods[] = { ph.method, -1 };
|
int tmp_methods[] = { ph.method, M_END };
|
||||||
const int *methods = NULL;
|
const int *methods = NULL;
|
||||||
if (opt->all_methods)
|
if (opt->all_methods)
|
||||||
methods = getCompressionMethods(-1, ph.level);
|
methods = getCompressionMethods(-1, ph.level);
|
||||||
if (methods == NULL)
|
if (methods == NULL)
|
||||||
methods = tmp_methods;
|
methods = tmp_methods;
|
||||||
int nmethods = 0;
|
int nmethods = 0;
|
||||||
while (methods[nmethods] >= 0)
|
for (int mm = 0; methods[mm] != M_END; ++mm)
|
||||||
{
|
{
|
||||||
assert(isValidCompressionMethod(methods[nmethods]));
|
if (methods[mm] == M_SKIP)
|
||||||
|
continue;
|
||||||
|
if (opt->all_methods && !opt->all_methods_use_lzma && methods[mm] == M_LZMA)
|
||||||
|
continue;
|
||||||
|
assert(isValidCompressionMethod(methods[mm]));
|
||||||
nmethods++;
|
nmethods++;
|
||||||
}
|
}
|
||||||
assert(nmethods > 0);
|
assert(nmethods > 0);
|
||||||
|
|
||||||
// update total_passes; previous (0 < ui_total_passes) means incremental
|
// update total_passes; previous (0 < ui_total_passes) means incremental
|
||||||
if (strategy < 0)
|
if (strategy < 0)
|
||||||
ui_total_passes += 1 * nmethods - (0 < ui_total_passes);
|
uip->ui_total_passes += 1 * nmethods - (0 < uip->ui_total_passes);
|
||||||
else
|
else
|
||||||
ui_total_passes += nfilters * nmethods - (0 < ui_total_passes);
|
uip->ui_total_passes += nfilters * nmethods - (0 < uip->ui_total_passes);
|
||||||
|
|
||||||
// Working buffer for compressed data. Don't waste memory.
|
// Working buffer for compressed data. Don't waste memory.
|
||||||
MemBuffer *otemp = &obuf;
|
MemBuffer *otemp = &obuf;
|
||||||
@@ -1399,20 +1231,23 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||||||
|
|
||||||
// compress
|
// compress
|
||||||
int nfilters_success = 0;
|
int nfilters_success = 0;
|
||||||
for (int m = 0; m < nmethods; m++) // for all methods
|
for (int mm = 0; methods[mm] != M_END; ++mm) // for all methods
|
||||||
{
|
{
|
||||||
|
if (methods[mm] == M_SKIP)
|
||||||
|
continue;
|
||||||
|
if (opt->all_methods && !opt->all_methods_use_lzma && methods[mm] == M_LZMA)
|
||||||
|
continue;
|
||||||
unsigned hdr_c_len = 0;
|
unsigned hdr_c_len = 0;
|
||||||
if (hdr_buf && hdr_u_len)
|
if (hdr_buf && hdr_u_len)
|
||||||
{
|
{
|
||||||
unsigned result[16];
|
if (nfilters_success != 0 && otemp == &obuf)
|
||||||
upx_compress_config_t conf;
|
{
|
||||||
memset(&conf, 0xff, sizeof(conf));
|
// do not overwrite obuf
|
||||||
if (0 < m && otemp == &obuf) { // do not overwrite obuf
|
|
||||||
otemp_buf.allocForCompression(compress_buf_len);
|
otemp_buf.allocForCompression(compress_buf_len);
|
||||||
otemp = &otemp_buf;
|
otemp = &otemp_buf;
|
||||||
}
|
}
|
||||||
int r = upx_compress(hdr_buf, hdr_u_len, *otemp, &hdr_c_len,
|
int r = upx_compress(hdr_buf, hdr_u_len, *otemp, &hdr_c_len,
|
||||||
0, methods[m], 10, &conf, result);
|
NULL, methods[mm], 10, NULL, NULL);
|
||||||
if (r != UPX_E_OK)
|
if (r != UPX_E_OK)
|
||||||
throwInternalError("header compression failed");
|
throwInternalError("header compression failed");
|
||||||
if (hdr_c_len >= hdr_u_len)
|
if (hdr_c_len >= hdr_u_len)
|
||||||
@@ -1424,7 +1259,7 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||||||
obuf.checkState();
|
obuf.checkState();
|
||||||
// get fresh packheader
|
// get fresh packheader
|
||||||
ph = orig_ph;
|
ph = orig_ph;
|
||||||
ph.method = methods[m];
|
ph.method = methods[mm];
|
||||||
ph.filter = filters[i];
|
ph.filter = filters[i];
|
||||||
ph.overlap_overhead = 0;
|
ph.overlap_overhead = 0;
|
||||||
// get fresh filter
|
// get fresh filter
|
||||||
@@ -1445,8 +1280,8 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||||||
if (strategy > 0)
|
if (strategy > 0)
|
||||||
{
|
{
|
||||||
// adjust passes
|
// adjust passes
|
||||||
if (ui_pass >= 0)
|
if (uip->ui_pass >= 0)
|
||||||
ui_pass++;
|
uip->ui_pass++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1455,7 +1290,7 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||||||
printf("filter: id 0x%02x size %6d, calls %5d/%5d/%3d/%5d/%5d, cto 0x%02x\n",
|
printf("filter: id 0x%02x size %6d, calls %5d/%5d/%3d/%5d/%5d, cto 0x%02x\n",
|
||||||
ft.id, ft.buf_len, ft.calls, ft.noncalls, ft.wrongcalls, ft.firstcall, ft.lastcall, ft.cto);
|
ft.id, ft.buf_len, ft.calls, ft.noncalls, ft.wrongcalls, ft.firstcall, ft.lastcall, ft.cto);
|
||||||
#endif
|
#endif
|
||||||
if (nfilters_success > 0 && otemp == &obuf)
|
if (nfilters_success != 0 && otemp == &obuf)
|
||||||
{
|
{
|
||||||
otemp_buf.allocForCompression(compress_buf_len);
|
otemp_buf.allocForCompression(compress_buf_len);
|
||||||
otemp = &otemp_buf;
|
otemp = &otemp_buf;
|
||||||
@@ -1464,7 +1299,7 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||||||
ph.filter_cto = ft.cto;
|
ph.filter_cto = ft.cto;
|
||||||
ph.n_mru = ft.n_mru;
|
ph.n_mru = ft.n_mru;
|
||||||
// compress
|
// compress
|
||||||
if (compress(ibuf + compress_buf_off, *otemp, max_offset, max_match))
|
if (compress(ibuf + compress_buf_off, *otemp, cconf))
|
||||||
{
|
{
|
||||||
unsigned lsize = 0;
|
unsigned lsize = 0;
|
||||||
if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len)
|
if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len)
|
||||||
|
|||||||
+44
-38
@@ -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-2004 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2004 Laszlo Molnar
|
Copyright (C) 1996-2006 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,7 +36,6 @@ class OutputFile;
|
|||||||
class Packer;
|
class Packer;
|
||||||
class PackMaster;
|
class PackMaster;
|
||||||
class UiPacker;
|
class UiPacker;
|
||||||
class Linker;
|
|
||||||
class Filter;
|
class Filter;
|
||||||
|
|
||||||
|
|
||||||
@@ -84,6 +83,7 @@ public:
|
|||||||
long buf_offset;
|
long buf_offset;
|
||||||
|
|
||||||
// info fields set by Packer::compress()
|
// info fields set by Packer::compress()
|
||||||
|
upx_compress_result_t compress_result;
|
||||||
//unsigned min_offset_found;
|
//unsigned min_offset_found;
|
||||||
unsigned max_offset_found;
|
unsigned max_offset_found;
|
||||||
//unsigned min_match_found;
|
//unsigned min_match_found;
|
||||||
@@ -98,8 +98,17 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool ph_skipVerify(const PackHeader &ph);
|
||||||
|
void ph_decompress(PackHeader &ph, const upx_bytep in, upx_bytep out,
|
||||||
|
bool verify_checksum, Filter *ft);
|
||||||
|
bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf,
|
||||||
|
unsigned overlap_overhead);
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// abstract base class for packers
|
// abstract base class for packers
|
||||||
|
//
|
||||||
|
// FIXME: this class is way too fat and badly needs a decomposition
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class Packer
|
class Packer
|
||||||
@@ -159,7 +168,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// main compression drivers
|
// main compression drivers
|
||||||
virtual bool compress(upx_bytep in, upx_bytep out,
|
virtual bool compress(upx_bytep in, upx_bytep out,
|
||||||
unsigned max_offset = 0, unsigned max_match = 0);
|
const upx_compress_config_t *cconf = NULL);
|
||||||
virtual void decompress(const upx_bytep in, upx_bytep out,
|
virtual void decompress(const upx_bytep in, upx_bytep out,
|
||||||
bool verify_checksum = true, Filter *ft = NULL);
|
bool verify_checksum = true, Filter *ft = NULL);
|
||||||
virtual bool checkCompressionRatio(unsigned u_len, unsigned c_len) const;
|
virtual bool checkCompressionRatio(unsigned u_len, unsigned c_len) const;
|
||||||
@@ -170,7 +179,7 @@ protected:
|
|||||||
const unsigned overlap_range,
|
const unsigned overlap_range,
|
||||||
int strategy = 0,
|
int strategy = 0,
|
||||||
const int *filters = NULL,
|
const int *filters = NULL,
|
||||||
unsigned max_offset = 0, unsigned max_match = 0,
|
const upx_compress_config_t *cconf = NULL,
|
||||||
unsigned filter_buf_off = 0,
|
unsigned filter_buf_off = 0,
|
||||||
unsigned compress_buf_off = 0,
|
unsigned compress_buf_off = 0,
|
||||||
unsigned char *header_buffer = 0,
|
unsigned char *header_buffer = 0,
|
||||||
@@ -187,14 +196,39 @@ protected:
|
|||||||
// destructive decompress + verify
|
// destructive decompress + verify
|
||||||
virtual void verifyOverlappingDecompression(Filter *ft = NULL);
|
virtual void verifyOverlappingDecompression(Filter *ft = NULL);
|
||||||
|
|
||||||
|
|
||||||
// packheader handling
|
// packheader handling
|
||||||
virtual int patchPackHeader(void *b, int blen);
|
virtual int patchPackHeader(void *b, int blen);
|
||||||
virtual bool getPackHeader(void *b, int blen);
|
virtual bool getPackHeader(void *b, int blen);
|
||||||
virtual bool readPackHeader(int len);
|
virtual bool readPackHeader(int len);
|
||||||
virtual void checkAlreadyPacked(void *b, int blen);
|
virtual void checkAlreadyPacked(const void *b, int blen);
|
||||||
|
|
||||||
// filter handling [see packerf.cpp]
|
// loader core
|
||||||
|
virtual int buildLoader(const Filter *ft) = 0;
|
||||||
|
virtual Linker* newLinker() const = 0;
|
||||||
|
// loader util for linker
|
||||||
|
virtual void freezeLoader();
|
||||||
|
virtual upx_byte *getLoader() const;
|
||||||
|
virtual int getLoaderSize() const;
|
||||||
|
virtual void initLoader(const void *pdata, int plen, int small=-1);
|
||||||
|
#if 1 && (ACC_CC_GNUC >= 0x040100)
|
||||||
|
virtual void __acc_cdecl_va addLoader(const char *s, ...) __attribute__((__sentinel__));
|
||||||
|
#else
|
||||||
|
virtual void __acc_cdecl_va addLoader(const char *s, ...);
|
||||||
|
#endif
|
||||||
|
virtual int getLoaderSection(const char *name, int *slen=NULL) const;
|
||||||
|
virtual int getLoaderSectionStart(const char *name, int *slen=NULL) const;
|
||||||
|
|
||||||
|
// compression handling [see packer_c.cpp]
|
||||||
|
public:
|
||||||
|
static bool isValidCompressionMethod(int method);
|
||||||
|
protected:
|
||||||
|
const int *getDefaultCompressionMethods_8(int method, int level, int small=-1) const;
|
||||||
|
const int *getDefaultCompressionMethods_le32(int method, int level, int small=-1) const;
|
||||||
|
virtual const char *getDecompressorSections() const;
|
||||||
|
virtual unsigned getDecompressorWrkmemSize() const;
|
||||||
|
virtual void defineDecompressorSymbols();
|
||||||
|
|
||||||
|
// filter handling [see packer_f.cpp]
|
||||||
virtual bool isValidFilter(int filter_id) const;
|
virtual bool isValidFilter(int filter_id) const;
|
||||||
virtual void tryFilters(Filter *ft, upx_byte *buf, unsigned buf_len,
|
virtual void tryFilters(Filter *ft, upx_byte *buf, unsigned buf_len,
|
||||||
unsigned addvalue=0) const;
|
unsigned addvalue=0) const;
|
||||||
@@ -203,22 +237,6 @@ protected:
|
|||||||
virtual void optimizeFilter(Filter *, const upx_byte *, unsigned) const
|
virtual void optimizeFilter(Filter *, const upx_byte *, unsigned) const
|
||||||
{ }
|
{ }
|
||||||
virtual void addFilter32(int filter_id);
|
virtual void addFilter32(int filter_id);
|
||||||
virtual bool patchFilter32(void *, int, const Filter *ft);
|
|
||||||
|
|
||||||
// loader util
|
|
||||||
virtual int buildLoader(const Filter *) { return getLoaderSize(); }
|
|
||||||
virtual const upx_byte *getLoader() const;
|
|
||||||
virtual int getLoaderSize() const;
|
|
||||||
virtual void initLoader(const void *pdata, int plen, int pinfo=-1, int small=-1);
|
|
||||||
#if 1 && (ACC_CC_GNUC >= 0x040100)
|
|
||||||
virtual void __acc_cdecl_va addLoader(const char *s, ...) __attribute__((__sentinel__));
|
|
||||||
#else
|
|
||||||
virtual void __acc_cdecl_va addLoader(const char *s, ...);
|
|
||||||
#endif
|
|
||||||
virtual int getLoaderSection(const char *name, int *slen=NULL) const;
|
|
||||||
virtual int getLoaderSectionStart(const char *name, int *slen=NULL) const;
|
|
||||||
virtual const char *getDecompressor() const;
|
|
||||||
virtual const char *getIdentstr(unsigned *size, int small=-1);
|
|
||||||
|
|
||||||
// stub and overlay util
|
// stub and overlay util
|
||||||
static void handleStub(InputFile *fi, OutputFile *fo, long size);
|
static void handleStub(InputFile *fi, OutputFile *fo, long size);
|
||||||
@@ -238,19 +256,11 @@ protected:
|
|||||||
int patch_le16(void *b, int blen, const void * old, unsigned new_);
|
int patch_le16(void *b, int blen, const void * old, unsigned new_);
|
||||||
int patch_le32(void *b, int blen, unsigned old, unsigned new_);
|
int patch_le32(void *b, int blen, unsigned old, unsigned new_);
|
||||||
int patch_le32(void *b, int blen, const void * old, unsigned new_);
|
int patch_le32(void *b, int blen, const void * old, unsigned new_);
|
||||||
int patchVersion(void *b, int blen);
|
|
||||||
int patchVersionYear(void *b, int blen);
|
|
||||||
void checkPatch(void *b, int blen, int boff, int size);
|
void checkPatch(void *b, int blen, int boff, int size);
|
||||||
|
|
||||||
// relocation util
|
// relocation util
|
||||||
virtual upx_byte *optimizeReloc32(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big);
|
static upx_byte *optimizeReloc32(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big);
|
||||||
virtual unsigned unoptimizeReloc32(upx_byte **in,upx_byte *image,MemBuffer *out,int bs);
|
static unsigned unoptimizeReloc32(upx_byte **in,upx_byte *image,MemBuffer *out,int bs);
|
||||||
|
|
||||||
// compression method util
|
|
||||||
const int *getDefaultCompressionMethods_8(int method, int level, int small=-1) const;
|
|
||||||
const int *getDefaultCompressionMethods_le32(int method, int level, int small=-1) const;
|
|
||||||
public:
|
|
||||||
static bool isValidCompressionMethod(int method);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InputFile *fi;
|
InputFile *fi;
|
||||||
@@ -265,13 +275,9 @@ protected:
|
|||||||
|
|
||||||
// UI handler
|
// UI handler
|
||||||
UiPacker *uip;
|
UiPacker *uip;
|
||||||
int ui_pass;
|
|
||||||
int ui_total_passes;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// linker
|
// linker
|
||||||
Linker *linker;
|
Linker *linker;
|
||||||
virtual void createLinker(const void *pdata, int plen, int pinfo);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// private to checkPatch()
|
// private to checkPatch()
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user