Compare commits
141 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 747e8370e0 | |||
| 2c67875781 | |||
| c96e8a8c19 | |||
| 5f203fc082 | |||
| b943c9b471 | |||
| 1a90a1daa8 | |||
| 72dfc743fd | |||
| 465307655b | |||
| 6ce71e6694 | |||
| 7f01b3b92a | |||
| 76950d56b9 | |||
| c11e0d02b3 | |||
| 4c798c1718 | |||
| 450d7e9ad4 | |||
| b8ab79c83e | |||
| 6934bdd533 | |||
| 84dedb73a5 | |||
| 8964aa5221 | |||
| 3481ae236c | |||
| 46adc5f8a4 | |||
| 5296df5899 | |||
| 13dad4be16 | |||
| b5d0c343b4 | |||
| b00b945264 | |||
| 3bda09e105 | |||
| 32d32c4e4a | |||
| 497441b54e | |||
| 9c564fd4c7 | |||
| 0c2263d0e9 | |||
| 3d4d30766d | |||
| 99d84d44fc | |||
| 41ba7077ad | |||
| 8a929a91c3 | |||
| 0604f06841 | |||
| 229924adf9 | |||
| df988b7c69 | |||
| e8106e2e34 | |||
| c21d3e24f8 | |||
| 2d87aa0753 | |||
| b2ad4dc9a0 | |||
| 370f2ea98f | |||
| a05ca565ff | |||
| 52255637f2 | |||
| 0fcaa3a2f5 | |||
| 0e2fa6eb9d | |||
| 1aac462c83 | |||
| 2a0edfd8f7 | |||
| 1f59a9f846 | |||
| 80c20a90ea | |||
| 56a35649fe | |||
| f07cea0b79 | |||
| 4c1b08a281 | |||
| 117f9eddcd | |||
| 7bbbfce482 | |||
| f37a7811f9 | |||
| 9173c10239 | |||
| 318b31550d | |||
| c18ebc63a6 | |||
| d704694272 | |||
| 1cfec3bdf7 | |||
| fe6ea6bc10 | |||
| d29c8df45e | |||
| 71f996af95 | |||
| d9722ad6b3 | |||
| 398fd8028c | |||
| 1345a3cfd3 | |||
| 7eb0b195b8 | |||
| 009caee82d | |||
| 3bdc805a22 | |||
| ac457792b4 | |||
| 1377b54b9e | |||
| 66418ffc8c | |||
| b4c4b1fb70 | |||
| ffe4a4b047 | |||
| 753ce45310 | |||
| fece0d73e7 | |||
| edce076e68 | |||
| 675d0a009a | |||
| 5d41b5a4db | |||
| fe53b135eb | |||
| 5b1c154ee2 | |||
| 816d882611 | |||
| 12bcb09051 | |||
| c59c69a85f | |||
| bdd0daaf6f | |||
| cfad7c8356 | |||
| b2b8a128d0 | |||
| 1cfad80ca2 | |||
| a5a80e41b8 | |||
| 152f8e92bf | |||
| 0323560b49 | |||
| d3bc84a2f7 | |||
| 8a82c259bd | |||
| 46009c7658 | |||
| 6f760308bd | |||
| c346f8f17d | |||
| af1d059fff | |||
| 5562b21a20 | |||
| 8f68f31877 | |||
| ce7e94030c | |||
| ccf5a1b972 | |||
| 0d5ae77efc | |||
| 1695096d18 | |||
| 6db0b7cf18 | |||
| 575b43b0d4 | |||
| 7b39b05894 | |||
| 8bea9e0a5e | |||
| 2255b32e45 | |||
| b62573ae8f | |||
| 44ed84f5cf | |||
| d008c834be | |||
| 2d3a914aee | |||
| 7324f4c3d1 | |||
| 50c8860a50 | |||
| 6456de7188 | |||
| 23c629f2aa | |||
| 2bf154f74f | |||
| b598ad1bc0 | |||
| ace24ad68e | |||
| 750c1a0f27 | |||
| 52d89bd66b | |||
| 8cfb9d35e9 | |||
| 2f529158a0 | |||
| 6e68ab6d9e | |||
| 7a3c55af35 | |||
| fb39d6304a | |||
| 4cb57d9059 | |||
| 42d69bd0e5 | |||
| f27b399f81 | |||
| a545a3938f | |||
| d1e352c9ee | |||
| 99be1e798b | |||
| 2132a28a17 | |||
| 8b1cc28783 | |||
| 78364ac830 | |||
| 6e5f5732b5 | |||
| 87844254d1 | |||
| 08ef9f69fb | |||
| 5fbd1b78e7 | |||
| 39f5eb753f | |||
| f4cbe3f300 |
@@ -2,11 +2,15 @@ syntax: regexp
|
|||||||
|
|
||||||
^\.bzr
|
^\.bzr
|
||||||
^ChangeLog
|
^ChangeLog
|
||||||
|
^Makevars.global
|
||||||
^build
|
^build
|
||||||
^maint
|
^maint
|
||||||
|
|
||||||
syntax: glob
|
syntax: glob
|
||||||
|
|
||||||
|
.depend
|
||||||
|
Makevars.local
|
||||||
|
|
||||||
*.a
|
*.a
|
||||||
*.dll
|
*.dll
|
||||||
*.lib
|
*.lib
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||||
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
|
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
|
||||||
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||||
|
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
|
||||||
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
||||||
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
||||||
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
||||||
@@ -12,3 +13,4 @@ c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
|||||||
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
|
d276aa09033c24d0981bc3f4fee5628aecc988ad RELEASE_290
|
||||||
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
||||||
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
||||||
|
efa52753e366300c0e0ebe20631adcb24ed3c15b RELEASE_293
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
#
|
#
|
||||||
# UPX toplevel Makefile - needs GNU make 3.80 or better
|
# UPX toplevel Makefile - needs GNU make 3.81 or better
|
||||||
#
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
export SHELL = /bin/sh
|
export SHELL = /bin/sh
|
||||||
|
|
||||||
|
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||||
|
$(error GNU make 3.81 or better is required)
|
||||||
|
endif
|
||||||
|
|
||||||
srcdir = .
|
srcdir = .
|
||||||
top_srcdir = .
|
top_srcdir = .
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
|
|
||||||
|
|
||||||
# info: src/stub needs GNU make 3.81 and special build tools
|
# info: src/stub needs special build tools
|
||||||
BUILD_STUB = 0
|
BUILD_STUB = 0
|
||||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||||
BUILD_STUB = 1
|
BUILD_STUB = 1
|
||||||
@@ -18,9 +23,6 @@ endif
|
|||||||
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||||
BUILD_STUB = 1
|
BUILD_STUB = 1
|
||||||
endif
|
endif
|
||||||
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.79 3.79.1 3.80),)
|
|
||||||
BUILD_STUB = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -33,15 +35,14 @@ endif
|
|||||||
$(MAKE) -C src $@
|
$(MAKE) -C src $@
|
||||||
$(MAKE) -C doc $@
|
$(MAKE) -C doc $@
|
||||||
|
|
||||||
# automatically generate ChangeLog from Mercurial repo
|
|
||||||
ChangeLog:
|
|
||||||
ifneq ($(wildcard .hg/data/.),)
|
ifneq ($(wildcard .hg/data/.),)
|
||||||
|
# automatically generate ChangeLog from local Mercurial repo
|
||||||
|
ChangeLog:
|
||||||
hg log --style=changelog > $@
|
hg log --style=changelog > $@
|
||||||
else
|
.PHONY: ChangeLog
|
||||||
@echo "UPX info: no hg repo found"
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||||
.PHONY: ChangeLog
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,19 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
Changes in 3.00 (27 Apr 2007):
|
||||||
|
* watcom/le & tmt/adam: fixed a problem when using certain filters
|
||||||
|
|
||||||
|
Changes in 2.93 beta (08 Mar 2007):
|
||||||
|
* new formats Mach/i386 and Mach/fat support Mac OS X i686 and
|
||||||
|
Universal binaries [i686 and PowerPC only]
|
||||||
|
* dos/exe: LZMA is now also supported for 16-bit dos/exe. Please note that
|
||||||
|
you have to explicitly use '--lzma' even for '--ultra-brute' here
|
||||||
|
because runtime decompression is about 30 times slower than NRV -
|
||||||
|
which is really noticeable on old machines.
|
||||||
|
* dos/exe: fixed a rarely occuring bug in relocation handling
|
||||||
|
* win32/pe & arm/pe: better icon compression handling
|
||||||
|
|
||||||
Changes in 2.92 beta (23 Jan 2007):
|
Changes in 2.92 beta (23 Jan 2007):
|
||||||
* new option '--ultra-brute' which tries even more variants
|
* new option '--ultra-brute' which tries even more variants
|
||||||
* slightly improved compression ratio for some files when
|
* slightly improved compression ratio for some files when
|
||||||
@@ -302,8 +315,8 @@ Changes in 0.80 (03 Aug 1999)
|
|||||||
* win32/pe: even better TLS support
|
* win32/pe: even better TLS support
|
||||||
* win32/pe: versioninfo works on NT
|
* win32/pe: versioninfo works on NT
|
||||||
* win32/pe: import by ordinal from kernel32.dll works
|
* win32/pe: import by ordinal from kernel32.dll works
|
||||||
* win32/pe: other import improvements: importing a nonexistant DLL
|
* win32/pe: other import improvements: importing a nonexistent DLL
|
||||||
results in a usual Windows message, importing a nonexistant function
|
results in a usual Windows message, importing a nonexistent function
|
||||||
results in program exit (instead of crash ;-)
|
results in program exit (instead of crash ;-)
|
||||||
* win32/pe: new option: '--compress-resources=0'
|
* win32/pe: new option: '--compress-resources=0'
|
||||||
* win32/pe: reduced memory requirement during uncompression, some
|
* win32/pe: reduced memory requirement during uncompression, some
|
||||||
@@ -355,7 +368,7 @@ Changes in 0.60 (06 Mar 1999)
|
|||||||
* win32/pe: fixed file corruption when the size of the export data is invalid
|
* win32/pe: fixed file corruption when the size of the export data is invalid
|
||||||
* win32/pe: fixed a problem with empty resource data
|
* win32/pe: fixed a problem with empty resource data
|
||||||
* win32/pe: compressed file alignment set to minimum value
|
* win32/pe: compressed file alignment set to minimum value
|
||||||
* win32/pe: made all compressed sections writeable
|
* win32/pe: made all compressed sections writable
|
||||||
* fixed some other win32/pe bugs
|
* fixed some other win32/pe bugs
|
||||||
* fixed an address optimization problem for some not Watcom LE files
|
* fixed an address optimization problem for some not Watcom LE files
|
||||||
* fixed a bug which could make UPX hang when an exe header contained
|
* fixed a bug which could make UPX hang when an exe header contained
|
||||||
@@ -396,3 +409,5 @@ Changes in 0.20 (05 Jul 1998)
|
|||||||
Changes in 0.05 (26 May 1998)
|
Changes in 0.05 (26 May 1998)
|
||||||
* first public beta release
|
* first public beta release
|
||||||
|
|
||||||
|
|
||||||
|
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ THE FUTURE
|
|||||||
- We will *NOT* add any sort of protection and/or encryption.
|
- We will *NOT* add any sort of protection and/or encryption.
|
||||||
This only gives people a false feeling of security because
|
This only gives people a false feeling of security because
|
||||||
by definition all protectors/compressors can be broken.
|
by definition all protectors/compressors can be broken.
|
||||||
And don't trust any advertisment of authors of other executable
|
And don't trust any advertisement of authors of other executable
|
||||||
compressors about this topic - just do a websearch on "unpackers"...
|
compressors about this topic - just do a websearch on "unpackers"...
|
||||||
|
|
||||||
- Fix all remaining bugs - keep your reports coming ;-)
|
- Fix all remaining bugs - keep your reports coming ;-)
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ Subroutine do_xmap() of src/stub/l_lx_elf.c performs the
|
|||||||
"virtual execve()" using the compressed data as source, and stores
|
"virtual execve()" using the compressed data as source, and stores
|
||||||
the decompressed bytes directly into the appropriate virtual addresses.
|
the decompressed bytes directly into the appropriate virtual addresses.
|
||||||
|
|
||||||
Before transfering control to the PT_INTERP "program interpreter",
|
Before transferring control to the PT_INTERP "program interpreter",
|
||||||
minor tricks are required to setup the Elf32_auxv_t entries,
|
minor tricks are required to setup the Elf32_auxv_t entries,
|
||||||
clear the free portion of the stack (to compensate for ld-linux.so.2
|
clear the free portion of the stack (to compensate for ld-linux.so.2
|
||||||
assuming that its automatic stack variables are initialized to zero),
|
assuming that its automatic stack variables are initialized to zero),
|
||||||
|
|||||||
+1
-1
@@ -45,6 +45,6 @@ These symbols can be defined later in C++ using
|
|||||||
|
|
||||||
linker->defineSymbol("xx", yy)
|
linker->defineSymbol("xx", yy)
|
||||||
|
|
||||||
This functionality (we could say it's a simple linker) is achived by
|
This functionality (we could say it's a simple linker) is achieved by
|
||||||
compiling the assembly into an ELF object file which a little C++
|
compiling the assembly into an ELF object file which a little C++
|
||||||
module (src/linker.cpp) can interpret and work with.
|
module (src/linker.cpp) can interpret and work with.
|
||||||
|
|||||||
+22
-19
@@ -197,7 +197,7 @@ For win32/pe programs there's B<--strip-relocs=0>. See notes below.
|
|||||||
|
|
||||||
=head1 OVERLAY HANDLING OPTIONS
|
=head1 OVERLAY HANDLING OPTIONS
|
||||||
|
|
||||||
Info: An "overlay" means auxillary data atached after the logical end of
|
Info: An "overlay" means auxiliary data attached after the logical end of
|
||||||
an executable, and it often contains application specific data
|
an executable, and it often contains application specific data
|
||||||
(this is a common practice to avoid an extra data file, though
|
(this is a common practice to avoid an extra data file, though
|
||||||
it would be better to use resource sections).
|
it would be better to use resource sections).
|
||||||
@@ -345,7 +345,7 @@ Extra options available for this executable format:
|
|||||||
First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has
|
First of all, it is recommended to use B<UPX> *instead* of B<strip>. strip has
|
||||||
the very bad habit of replacing your stub with its own (outdated) version.
|
the very bad habit of replacing your stub with its own (outdated) version.
|
||||||
Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it
|
Additionally B<UPX> corrects a bug/feature in strip v2.8.x: it
|
||||||
will fix the 4 KByte aligment of the stub.
|
will fix the 4 KByte alignment of the stub.
|
||||||
|
|
||||||
B<UPX> includes the full functionality of stubify. This means it will
|
B<UPX> includes the full functionality of stubify. This means it will
|
||||||
automatically stubify your COFF files. Use the option B<--coff> to
|
automatically stubify your COFF files. Use the option B<--coff> to
|
||||||
@@ -380,7 +380,7 @@ Extra options available for this executable format:
|
|||||||
Introduction
|
Introduction
|
||||||
|
|
||||||
Linux/386 support in UPX consists of 3 different executable formats,
|
Linux/386 support in UPX consists of 3 different executable formats,
|
||||||
one optimized for ELF excutables ("linux/elf386"), one optimized
|
one optimized for ELF executables ("linux/elf386"), one optimized
|
||||||
for shell scripts ("linux/sh386"), and one generic format
|
for shell scripts ("linux/sh386"), and one generic format
|
||||||
("linux/386").
|
("linux/386").
|
||||||
|
|
||||||
@@ -408,14 +408,14 @@ General user's overview
|
|||||||
or network I/O.
|
or network I/O.
|
||||||
|
|
||||||
Depending on the statistics of usage and access, and the relative
|
Depending on the statistics of usage and access, and the relative
|
||||||
speeds of CPU, RAM, swap space, /tmp, and filesystem storage, then
|
speeds of CPU, RAM, swap space, /tmp, and file system storage, then
|
||||||
invoking and running a compressed executable can be faster than
|
invoking and running a compressed executable can be faster than
|
||||||
directly running the corresponding uncompressed program.
|
directly running the corresponding uncompressed program.
|
||||||
The operating system might perfrom fewer expensive I/O operations
|
The operating system might perform fewer expensive I/O operations
|
||||||
to invoke the compressed program. Paging to or from swap space
|
to invoke the compressed program. Paging to or from swap space
|
||||||
or /tmp might be faster than paging from the general filesystem.
|
or /tmp might be faster than paging from the general file system.
|
||||||
``Medium-sized'' programs which access about 1/3 to 1/2 of their
|
``Medium-sized'' programs which access about 1/3 to 1/2 of their
|
||||||
stored program bytes can do particulary well with compression.
|
stored program bytes can do particularly well with compression.
|
||||||
Small programs tend not to benefit as much because the absolute
|
Small programs tend not to benefit as much because the absolute
|
||||||
savings is less. Big programs tend not to benefit proportionally
|
savings is less. Big programs tend not to benefit proportionally
|
||||||
because each invocation may use only a small fraction of the program,
|
because each invocation may use only a small fraction of the program,
|
||||||
@@ -424,7 +424,7 @@ General user's overview
|
|||||||
then compression may win anyway.
|
then compression may win anyway.
|
||||||
|
|
||||||
Currently, executables compressed by UPX do not share RAM at runtime
|
Currently, executables compressed by UPX do not share RAM at runtime
|
||||||
in the way that executables mapped from a filesystem do. As a
|
in the way that executables mapped from a file system do. As a
|
||||||
result, if the same program is run simultaneously by more than one
|
result, if the same program is run simultaneously by more than one
|
||||||
process, then using the compressed version will require more RAM and/or
|
process, then using the compressed version will require more RAM and/or
|
||||||
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
swap space. So, shell programs (bash, csh, etc.) and ``make''
|
||||||
@@ -513,7 +513,7 @@ The linux/elf386 format decompresses directly into RAM,
|
|||||||
uses only one exec, does not use space in /tmp,
|
uses only one exec, does not use space in /tmp,
|
||||||
and does not use /proc.
|
and does not use /proc.
|
||||||
|
|
||||||
Linux/elf386 is automatically selected for Linux ELF exectuables.
|
Linux/elf386 is automatically selected for Linux ELF executables.
|
||||||
|
|
||||||
Packed programs will be byte-identical to the original after uncompression.
|
Packed programs will be byte-identical to the original after uncompression.
|
||||||
|
|
||||||
@@ -602,7 +602,7 @@ Extra options available for this executable format:
|
|||||||
Please read the general Linux description first.
|
Please read the general Linux description first.
|
||||||
|
|
||||||
The generic linux/386 format decompresses to /tmp and needs
|
The generic linux/386 format decompresses to /tmp and needs
|
||||||
/proc filesystem support. It starts the decompressed program
|
/proc file system support. It starts the decompressed program
|
||||||
via the execve() syscall.
|
via the execve() syscall.
|
||||||
|
|
||||||
Linux/386 is only selected if the specialized linux/elf386
|
Linux/386 is only selected if the specialized linux/elf386
|
||||||
@@ -614,11 +614,11 @@ How it works:
|
|||||||
|
|
||||||
For files which are not ELF and not a script for a known "-c" shell,
|
For files which are not ELF and not a script for a known "-c" shell,
|
||||||
UPX uses kernel execve(), which first requires decompressing to a
|
UPX uses kernel execve(), which first requires decompressing to a
|
||||||
temporary file in the filesystem. Interestingly -
|
temporary file in the file system. Interestingly -
|
||||||
because of the good memory management of the Linux kernel - this
|
because of the good memory management of the Linux kernel - this
|
||||||
often does not introduce a noticable delay, and in fact there
|
often does not introduce a noticeable delay, and in fact there
|
||||||
will be no disk access at all if you have enough free memory as
|
will be no disk access at all if you have enough free memory as
|
||||||
the entire process takes places within the filesystem buffers.
|
the entire process takes places within the file system buffers.
|
||||||
|
|
||||||
A compressed executable consists of the UPX stub and an overlay
|
A compressed executable consists of the UPX stub and an overlay
|
||||||
which contains the original program in a compressed form.
|
which contains the original program in a compressed form.
|
||||||
@@ -644,7 +644,7 @@ Specific drawbacks:
|
|||||||
decompression, but you still need it for the full execution time
|
decompression, but you still need it for the full execution time
|
||||||
of the program.
|
of the program.
|
||||||
|
|
||||||
- You must have /proc filesystem support as the stub wants to open
|
- You must have /proc file system support as the stub wants to open
|
||||||
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
|
/proc/<pid>/exe and needs /proc/<pid>/fd/X. This also means that you
|
||||||
cannot compress programs that are used during the boot sequence
|
cannot compress programs that are used during the boot sequence
|
||||||
before /proc is mounted.
|
before /proc is mounted.
|
||||||
@@ -656,7 +656,7 @@ Specific drawbacks:
|
|||||||
|
|
||||||
- Because of temporary decompression to disk the decompression speed
|
- Because of temporary decompression to disk the decompression speed
|
||||||
is not as fast as with the other executable formats. Still, I can see
|
is not as fast as with the other executable formats. Still, I can see
|
||||||
no noticable delay when starting programs like my ~3 MB emacs (which
|
no noticeable delay when starting programs like my ~3 MB emacs (which
|
||||||
is less than 1 MB when compressed :-).
|
is less than 1 MB when compressed :-).
|
||||||
|
|
||||||
Extra options available for this executable format:
|
Extra options available for this executable format:
|
||||||
@@ -683,7 +683,10 @@ Notes:
|
|||||||
|
|
||||||
- UPX creates as default a suitable executable for CD-Mastering
|
- UPX creates as default a suitable executable for CD-Mastering
|
||||||
and console transfer. For a CD-Master main executable you could also try
|
and console transfer. For a CD-Master main executable you could also try
|
||||||
the special option "--boot-only" as descriped below.
|
the special option "--boot-only" as described below.
|
||||||
|
It has been reported that upx packed executables are fully compatible with
|
||||||
|
the Sony PlayStation 2 (PS2, PStwo) and Sony PlayStation Portable (PSP) in
|
||||||
|
Sony PlayStation (PSone) emulation mode.
|
||||||
|
|
||||||
- Normally the packed files use the same memory areas like the uncompressed
|
- Normally the packed files use the same memory areas like the uncompressed
|
||||||
versions, so they will not override other memory areas while unpacking.
|
versions, so they will not override other memory areas while unpacking.
|
||||||
@@ -759,7 +762,7 @@ Benefits:
|
|||||||
- Better compression (but note that the kernel was already compressed,
|
- Better compression (but note that the kernel was already compressed,
|
||||||
so the improvement is not as large as with other formats).
|
so the improvement is not as large as with other formats).
|
||||||
Still, the bytes saved may be essential for special needs like
|
Still, the bytes saved may be essential for special needs like
|
||||||
bootdisks.
|
boot disks.
|
||||||
|
|
||||||
For example, this is what I get for my 2.2.16 kernel:
|
For example, this is what I get for my 2.2.16 kernel:
|
||||||
1589708 vmlinux
|
1589708 vmlinux
|
||||||
@@ -806,13 +809,13 @@ Extra options available for this executable format:
|
|||||||
=head2 NOTES FOR WIN32/PE
|
=head2 NOTES FOR WIN32/PE
|
||||||
|
|
||||||
The PE support in B<UPX> is quite stable now, but probably there are
|
The PE support in B<UPX> is quite stable now, but probably there are
|
||||||
still some incompabilities with some files.
|
still some incompatibilities with some files.
|
||||||
|
|
||||||
Because of the way B<UPX> (and other packers for this format) works, you
|
Because of the way B<UPX> (and other packers for this format) works, you
|
||||||
can see increased memory usage of your compressed files because the whole
|
can see increased memory usage of your compressed files because the whole
|
||||||
program is loaded into memory at startup.
|
program is loaded into memory at startup.
|
||||||
If you start several instances of huge compressed programs you're
|
If you start several instances of huge compressed programs you're
|
||||||
wasting memory because the common segements of the program won't
|
wasting memory because the common segments of the program won't
|
||||||
get shared across the instances.
|
get shared across the instances.
|
||||||
On the other hand if you're compressing only smaller programs, or
|
On the other hand if you're compressing only smaller programs, or
|
||||||
running only one instance of larger programs, then this penalty is
|
running only one instance of larger programs, then this penalty is
|
||||||
|
|||||||
+36
-11
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# UPX Makefile - needs GNU make 3.80 or better
|
# UPX Makefile - needs GNU make 3.81 or better
|
||||||
#
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
@@ -7,9 +7,19 @@ MAKEFLAGS += -rR
|
|||||||
export SHELL = /bin/sh
|
export SHELL = /bin/sh
|
||||||
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
||||||
|
|
||||||
srcdir ?= $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||||
ifneq ($(srcdir),./)
|
$(error GNU make 3.81 or better is required)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef srcdir
|
||||||
|
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
||||||
|
endif
|
||||||
|
ifndef top_srcdir
|
||||||
|
top_srcdir := $(srcdir)/..
|
||||||
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
|
ifneq ($(srcdir),.)
|
||||||
##$(info Info: using VPATH . $(srcdir))
|
##$(info Info: using VPATH . $(srcdir))
|
||||||
VPATH := . $(srcdir)
|
VPATH := . $(srcdir)
|
||||||
endif
|
endif
|
||||||
@@ -17,11 +27,10 @@ endif
|
|||||||
ifeq ($(CXX),)
|
ifeq ($(CXX),)
|
||||||
CXX = g++
|
CXX = g++
|
||||||
endif
|
endif
|
||||||
ifeq ($(firstword $(CXX)),g++)
|
ifneq ($(findstring $(firstword $(CXX)),g++),)
|
||||||
USE_GNUC ?= 1
|
USE_GNUC ?= 1
|
||||||
endif
|
endif
|
||||||
ifeq ($(USE_GNUC),1)
|
ifeq ($(USE_GNUC),1)
|
||||||
CXXFLAGS += -MMD
|
|
||||||
ifeq ($(DEBUG),1)
|
ifeq ($(DEBUG),1)
|
||||||
CXXFLAGS += -O0 -g
|
CXXFLAGS += -O0 -g
|
||||||
else
|
else
|
||||||
@@ -48,22 +57,31 @@ endif
|
|||||||
LIBS += -lucl -lz
|
LIBS += -lucl -lz
|
||||||
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
|
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
|
||||||
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||||
DEFS += -DWITH_LZMA
|
DEFS += -DWITH_LZMA=1
|
||||||
INCLUDES += -I$(UPX_LZMADIR)
|
INCLUDES += -I$(UPX_LZMADIR)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
all: upx$(exeext)
|
all: upx$(exeext) | .depend
|
||||||
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS)
|
.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS) .depend
|
||||||
|
|
||||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||||
$($(notdir $@).PRE_LINK_STEP)
|
$($(notdir $@).PRE_LINK_STEP)
|
||||||
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
|
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
|
||||||
$($(notdir $@).POST_LINK_STEP)
|
$($(notdir $@).POST_LINK_STEP)
|
||||||
|
|
||||||
%.o : %.cpp
|
%.o : %.cpp | .depend
|
||||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||||
|
|
||||||
|
.depend: $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h) $(MAKEFILE_LIST)
|
||||||
|
@rm -f $@
|
||||||
|
ifeq ($(USE_GNUC),1)
|
||||||
|
@echo "Updating $@"
|
||||||
|
@$(strip $(CXX) $(call e,CPPFLAGS) -MM) $(filter %.cpp,$^) > $@
|
||||||
|
else
|
||||||
|
touch $@
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(USE_GNUC),1)
|
ifeq ($(USE_GNUC),1)
|
||||||
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
|
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
|
||||||
@@ -76,7 +94,14 @@ endif
|
|||||||
|
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
mostlyclean clean distclean maintainer-clean:
|
||||||
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
rm -f *.d *.map *.o *.obj *.res .depend upx.exe upx.out upx.ttp upx$(exeext)
|
||||||
|
|
||||||
-include *.d
|
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||||
|
|
||||||
|
ifeq ($(MAKECMDGOALS),mostlyclean)
|
||||||
|
else ifeq ($(MAKECMDGOALS),clean)
|
||||||
|
else ifeq ($(MAKECMDGOALS),distclean)
|
||||||
|
else ifeq ($(MAKECMDGOALS),maintainer-clean)
|
||||||
|
else
|
||||||
|
-include .depend
|
||||||
|
endif
|
||||||
|
|||||||
+7
-5
@@ -182,8 +182,10 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult )
|
const upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
@@ -201,15 +203,15 @@ int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
|||||||
}
|
}
|
||||||
#if defined(WITH_LZMA)
|
#if defined(WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_NRV)
|
#if defined(WITH_NRV)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
r = upx_nrv_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
r = upx_nrv_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_UCL)
|
#if defined(WITH_UCL)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
r = upx_ucl_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
|
|||||||
+16
-8
@@ -46,8 +46,10 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_lzma_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
@@ -65,8 +67,10 @@ int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_nrv_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_nrv_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
@@ -84,8 +88,10 @@ int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
@@ -102,8 +108,10 @@ int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_zlib_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+20
-15
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
|
||||||
void lzma_compress_config_t::reset()
|
void lzma_compress_config_t::reset()
|
||||||
@@ -483,28 +484,32 @@ error:
|
|||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_lzma_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult )
|
const upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
|
|
||||||
// FIXME - implement this
|
MemBuffer b(src_off + src_len);
|
||||||
// Note that Packer::verifyOverlappingDecompression() will
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
// verify the final result in any case.
|
unsigned saved_dst_len = *dst_len;
|
||||||
UNUSED(buf);
|
int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
||||||
|
if (r != UPX_E_OK)
|
||||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
return r;
|
||||||
//printf("upx_lzma_test_overlap: %d\n", overlap_overhead);
|
if (*dst_len != saved_dst_len)
|
||||||
if ((int)overlap_overhead >= 256)
|
return UPX_E_ERROR;
|
||||||
return UPX_E_OK;
|
// NOTE: there is a very tiny possibility that decompression has
|
||||||
|
// succeeded but the data is not restored correctly because of
|
||||||
UNUSED(cresult);
|
// in-place buffer overlapping.
|
||||||
return UPX_E_ERROR;
|
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -228,12 +228,15 @@ int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_ucl_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult )
|
const upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
UNUSED(tbuf); // not needed for UCL
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
|
|||||||
+20
-15
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
|
||||||
void zlib_compress_config_t::reset()
|
void zlib_compress_config_t::reset()
|
||||||
@@ -188,28 +189,32 @@ done:
|
|||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_zlib_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult )
|
const upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
|
|
||||||
// FIXME - implement this
|
MemBuffer b(src_off + src_len);
|
||||||
// Note that Packer::verifyOverlappingDecompression() will
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
// verify the final result in any case.
|
unsigned saved_dst_len = *dst_len;
|
||||||
UNUSED(buf);
|
int r = upx_zlib_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
||||||
|
if (r != UPX_E_OK)
|
||||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
return r;
|
||||||
//printf("upx_zlib_test_overlap: %d\n", overlap_overhead);
|
if (*dst_len != saved_dst_len)
|
||||||
if ((int)overlap_overhead >= 256)
|
return UPX_E_ERROR;
|
||||||
return UPX_E_OK;
|
// NOTE: there is a very tiny possibility that decompression has
|
||||||
|
// succeeded but the data is not restored correctly because of
|
||||||
UNUSED(cresult);
|
// in-place buffer overlapping.
|
||||||
return UPX_E_ERROR;
|
if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+12
-7
@@ -303,8 +303,8 @@
|
|||||||
|
|
||||||
#undef __attribute_packed
|
#undef __attribute_packed
|
||||||
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
|
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
|
||||||
# if (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386))
|
# if (ACC_ARCH_I386) && (ACC_CC_INTELC && (__INTEL_COMPILER < 800))
|
||||||
# define __attribute_packed
|
# elif (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386))
|
||||||
# else
|
# else
|
||||||
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
|
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
|
||||||
# endif
|
# endif
|
||||||
@@ -448,13 +448,14 @@ private:
|
|||||||
#define UPX_F_LINUX_ELFI_i386 20
|
#define UPX_F_LINUX_ELFI_i386 20
|
||||||
#define UPX_F_WINCE_ARM_PE 21
|
#define UPX_F_WINCE_ARM_PE 21
|
||||||
#define UPX_F_LINUX_ELF64_AMD 22
|
#define UPX_F_LINUX_ELF64_AMD 22
|
||||||
#define UPX_F_LINUX_ELF32_ARMLE 23
|
#define UPX_F_LINUX_ELF32_ARMEL 23
|
||||||
#define UPX_F_BSD_i386 24
|
#define UPX_F_BSD_i386 24
|
||||||
#define UPX_F_BSD_ELF_i386 25
|
#define UPX_F_BSD_ELF_i386 25
|
||||||
#define UPX_F_BSD_SH_i386 26
|
#define UPX_F_BSD_SH_i386 26
|
||||||
|
|
||||||
#define UPX_F_VMLINUX_AMD64 27
|
#define UPX_F_VMLINUX_AMD64 27
|
||||||
#define UPX_F_VMLINUX_ARM 28
|
#define UPX_F_VMLINUX_ARMEL 28
|
||||||
|
#define UPX_F_MACH_i386 29
|
||||||
|
|
||||||
#define UPX_F_PLAIN_TEXT 127
|
#define UPX_F_PLAIN_TEXT 127
|
||||||
|
|
||||||
@@ -462,7 +463,9 @@ private:
|
|||||||
#define UPX_F_SOLARIS_SPARC 130
|
#define UPX_F_SOLARIS_SPARC 130
|
||||||
#define UPX_F_MACH_PPC32 131
|
#define UPX_F_MACH_PPC32 131
|
||||||
#define UPX_F_LINUX_ELFPPC32 132
|
#define UPX_F_LINUX_ELFPPC32 132
|
||||||
#define UPX_F_LINUX_ELF32_ARMBE 133
|
#define UPX_F_LINUX_ELF32_ARMEB 133
|
||||||
|
#define UPX_F_MACH_FAT 134
|
||||||
|
#define UPX_F_VMLINUX_ARMEB 135
|
||||||
|
|
||||||
|
|
||||||
// compression methods
|
// compression methods
|
||||||
@@ -776,8 +779,10 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
int upx_test_overlap ( const upx_bytep buf,
|
||||||
unsigned src_len, unsigned* dst_len,
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
|
|
||||||
|
|||||||
+77
-6
@@ -69,7 +69,7 @@ void File::unlink(const char *name)
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
FileBase::FileBase() :
|
FileBase::FileBase() :
|
||||||
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL)
|
_fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0)
|
||||||
{
|
{
|
||||||
memset(&st,0,sizeof(st));
|
memset(&st,0,sizeof(st));
|
||||||
}
|
}
|
||||||
@@ -104,6 +104,10 @@ void FileBase::sopen()
|
|||||||
assert(0);
|
assert(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (!(_fd < 0)) {
|
||||||
|
::fstat(_fd, &st);
|
||||||
|
_length = st.st_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,6 +121,8 @@ bool FileBase::close()
|
|||||||
_flags = 0;
|
_flags = 0;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
_name = NULL;
|
_name = NULL;
|
||||||
|
_offset = 0;
|
||||||
|
_length = 0;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,10 +170,17 @@ void FileBase::seek(off_t off, int whence)
|
|||||||
{
|
{
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throwIOException("bad seek 1");
|
throwIOException("bad seek 1");
|
||||||
if (whence == SEEK_SET && off < 0)
|
if (whence == SEEK_SET) {
|
||||||
throwIOException("bad seek 2");
|
if (off < 0)
|
||||||
if (whence == SEEK_END && off > 0)
|
throwIOException("bad seek 2");
|
||||||
throwIOException("bad seek 3");
|
off += _offset;
|
||||||
|
}
|
||||||
|
if (whence == SEEK_END) {
|
||||||
|
if (off > 0)
|
||||||
|
throwIOException("bad seek 3");
|
||||||
|
off += _offset + _length;
|
||||||
|
whence = SEEK_SET;
|
||||||
|
}
|
||||||
if (::lseek(_fd,off,whence) < 0)
|
if (::lseek(_fd,off,whence) < 0)
|
||||||
throwIOException("seek error",errno);
|
throwIOException("seek error",errno);
|
||||||
}
|
}
|
||||||
@@ -180,7 +193,19 @@ off_t FileBase::tell() const
|
|||||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
throwIOException("tell error",errno);
|
throwIOException("tell error",errno);
|
||||||
return l;
|
return l - _offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileBase::set_extent(off_t offset, off_t length)
|
||||||
|
{
|
||||||
|
_offset = offset;
|
||||||
|
_length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t FileBase::st_size() const
|
||||||
|
{
|
||||||
|
return _length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -205,6 +230,8 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
|
_offset = 0;
|
||||||
|
_length = 0;
|
||||||
FileBase::sopen();
|
FileBase::sopen();
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
{
|
{
|
||||||
@@ -289,6 +316,8 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode)
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = shflags;
|
_shflags = shflags;
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
_offset = 0;
|
||||||
|
_length = 0;
|
||||||
FileBase::sopen();
|
FileBase::sopen();
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
{
|
{
|
||||||
@@ -316,6 +345,8 @@ bool OutputFile::openStdout(int flags, bool force)
|
|||||||
_flags = flags;
|
_flags = flags;
|
||||||
_shflags = -1;
|
_shflags = -1;
|
||||||
_mode = 0;
|
_mode = 0;
|
||||||
|
_offset = 0;
|
||||||
|
_length = 0;
|
||||||
if (flags && acc_set_binmode(fd, 1) == -1)
|
if (flags && acc_set_binmode(fd, 1) == -1)
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
_fd = fd;
|
_fd = fd;
|
||||||
@@ -329,6 +360,16 @@ void OutputFile::write(const void *buf, int len)
|
|||||||
bytes_written += len;
|
bytes_written += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
off_t OutputFile::st_size() const
|
||||||
|
{
|
||||||
|
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
|
||||||
|
return bytes_written; // too big if seek()+write() instead of rewrite()
|
||||||
|
}
|
||||||
|
struct stat my_st;
|
||||||
|
::fstat(_fd, &my_st);
|
||||||
|
return my_st.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OutputFile::write(const MemBuffer *buf, int len)
|
void OutputFile::write(const MemBuffer *buf, int len)
|
||||||
{
|
{
|
||||||
@@ -343,6 +384,36 @@ void OutputFile::write(const MemBuffer &buf, int len)
|
|||||||
write(&buf, len);
|
write(&buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputFile::rewrite(const void *buf, int len)
|
||||||
|
{
|
||||||
|
assert(!opt->to_stdout);
|
||||||
|
write(buf, len);
|
||||||
|
bytes_written -= len; // restore
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputFile::seek(off_t off, int whence)
|
||||||
|
{
|
||||||
|
assert(!opt->to_stdout);
|
||||||
|
super::seek(off,whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputFile::set_extent(off_t offset, off_t length)
|
||||||
|
{
|
||||||
|
super::set_extent(offset, length);
|
||||||
|
bytes_written = 0;
|
||||||
|
if (0==offset && (off_t)~0u==length) {
|
||||||
|
::fstat(_fd, &st);
|
||||||
|
_length = st.st_size - offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t OutputFile::unset_extent()
|
||||||
|
{
|
||||||
|
_offset = 0;
|
||||||
|
_length = ::lseek(_fd, 0, SEEK_END);
|
||||||
|
bytes_written = _length;
|
||||||
|
return _length;
|
||||||
|
}
|
||||||
|
|
||||||
void OutputFile::dump(const char *name, const void *buf, int len, int flags)
|
void OutputFile::dump(const char *name, const void *buf, int len, int flags)
|
||||||
{
|
{
|
||||||
|
|||||||
+9
-11
@@ -59,6 +59,8 @@ public:
|
|||||||
virtual bool isOpen() const { return _fd >= 0; }
|
virtual bool isOpen() const { return _fd >= 0; }
|
||||||
int getFd() const { return _fd; }
|
int getFd() const { return _fd; }
|
||||||
const char *getName() const { return _name; }
|
const char *getName() const { return _name; }
|
||||||
|
virtual off_t st_size() const; // { return _length; }
|
||||||
|
virtual void set_extent(off_t offset, off_t length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sopen();
|
void sopen();
|
||||||
@@ -73,6 +75,8 @@ protected:
|
|||||||
int _shflags;
|
int _shflags;
|
||||||
int _mode;
|
int _mode;
|
||||||
const char *_name;
|
const char *_name;
|
||||||
|
off_t _offset;
|
||||||
|
off_t _length;
|
||||||
public:
|
public:
|
||||||
struct stat st;
|
struct stat st;
|
||||||
};
|
};
|
||||||
@@ -128,21 +132,15 @@ public:
|
|||||||
virtual void write(const void *buf, int len);
|
virtual void write(const void *buf, int len);
|
||||||
virtual void write(const MemBuffer *buf, int len);
|
virtual void write(const MemBuffer *buf, int len);
|
||||||
virtual void write(const MemBuffer &buf, int len);
|
virtual void write(const MemBuffer &buf, int len);
|
||||||
|
virtual void set_extent(off_t offset, off_t length);
|
||||||
|
virtual off_t unset_extent(); // returns actual length
|
||||||
|
|
||||||
off_t getBytesWritten() const { return bytes_written; }
|
off_t getBytesWritten() const { return bytes_written; }
|
||||||
|
virtual off_t st_size() const; // { return _length; }
|
||||||
|
|
||||||
// FIXME - these won't work when using the '--stdout' option
|
// FIXME - these won't work when using the '--stdout' option
|
||||||
virtual void seek(off_t off, int whence)
|
virtual void seek(off_t off, int whence);
|
||||||
{
|
virtual void rewrite(const void *buf, int len);
|
||||||
assert(!opt->to_stdout);
|
|
||||||
super::seek(off,whence);
|
|
||||||
}
|
|
||||||
virtual void rewrite(const void *buf, int len)
|
|
||||||
{
|
|
||||||
assert(!opt->to_stdout);
|
|
||||||
write(buf, len);
|
|
||||||
bytes_written -= len; // restore
|
|
||||||
}
|
|
||||||
|
|
||||||
// util
|
// util
|
||||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||||
|
|||||||
+2
-2
@@ -205,8 +205,8 @@ void show_help(int verbose)
|
|||||||
con_fprintf(f,"\nCompression tuning options:\n");
|
con_fprintf(f,"\nCompression tuning options:\n");
|
||||||
fg = con_fg(f,fg);
|
fg = con_fg(f,fg);
|
||||||
con_fprintf(f,
|
con_fprintf(f,
|
||||||
" --brute try all available compression methods & filters\n"
|
" --brute try all available compression methods & filters [slow]\n"
|
||||||
" --ultra-brute try even more compression variants\n"
|
" --ultra-brute try even more compression variants [very slow]\n"
|
||||||
"\n");
|
"\n");
|
||||||
fg = con_fg(f,FG_YELLOW);
|
fg = con_fg(f,FG_YELLOW);
|
||||||
con_fprintf(f,"Backup options:\n");
|
con_fprintf(f,"Backup options:\n");
|
||||||
|
|||||||
+25
-2
@@ -228,15 +228,20 @@ void ElfLinker::preprocessSymbols(char *start, char *end)
|
|||||||
assert(nextl != NULL);
|
assert(nextl != NULL);
|
||||||
|
|
||||||
if (sscanf(start, "%x g *ABS* %x %1023s",
|
if (sscanf(start, "%x g *ABS* %x %1023s",
|
||||||
&value, &offset, symbol) == 3)
|
&value, &offset, symbol) == 3)
|
||||||
{
|
{
|
||||||
char *s = strstr(start, symbol);
|
char *s = strstr(start, symbol);
|
||||||
s[strlen(symbol)] = 0;
|
s[strlen(symbol)] = 0;
|
||||||
addSymbol(s, "*ABS*", value);
|
addSymbol(s, "*ABS*", value);
|
||||||
assert(offset == 0);
|
assert(offset == 0);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
else if (sscanf(start, "%x%*8c %1023s %*x %1023s",
|
else if (sscanf(start, "%x%*8c %1023s %*x %1023s",
|
||||||
&offset, section, symbol) == 3)
|
#else
|
||||||
|
// work around broken scanf implementations
|
||||||
|
else if (sscanf(start, "%x%*c%*c%*c%*c%*c%*c%*c%*c %1023s %*x %1023s",
|
||||||
|
#endif
|
||||||
|
&offset, section, symbol) == 3)
|
||||||
{
|
{
|
||||||
char *s = strstr(start, symbol);
|
char *s = strstr(start, symbol);
|
||||||
s[strlen(symbol)] = 0;
|
s[strlen(symbol)] = 0;
|
||||||
@@ -439,6 +444,23 @@ int ElfLinker::addLoader(const char *sname)
|
|||||||
return outputlen;
|
return outputlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElfLinker::addLoader(const char *s, va_list ap)
|
||||||
|
{
|
||||||
|
while (s != NULL)
|
||||||
|
{
|
||||||
|
addLoader(s);
|
||||||
|
s = va_arg(ap, const char *);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __acc_cdecl_va ElfLinker::addLoaderVA(const char *s, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, s);
|
||||||
|
addLoader(s, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
int ElfLinker::getSection(const char *sname, int *slen) const
|
int ElfLinker::getSection(const char *sname, int *slen) const
|
||||||
{
|
{
|
||||||
const Section *section = findSection(sname);
|
const Section *section = findSection(sname);
|
||||||
@@ -585,6 +607,7 @@ void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// ElfLinker arch subclasses
|
// ElfLinker arch subclasses
|
||||||
// FIXME: add more displacment overflow checks
|
// FIXME: add more displacment overflow checks
|
||||||
|
// FIXME: add support for our special "ignore_reloc_overflow" section
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if 0 // FIXME
|
#if 0 // FIXME
|
||||||
|
|||||||
@@ -83,6 +83,12 @@ public:
|
|||||||
virtual void init(const void *pdata, int plen);
|
virtual void init(const void *pdata, int plen);
|
||||||
//virtual void setLoaderAlignOffset(int phase);
|
//virtual void setLoaderAlignOffset(int phase);
|
||||||
virtual int addLoader(const char *sname);
|
virtual int addLoader(const char *sname);
|
||||||
|
void addLoader(const char *s, va_list ap);
|
||||||
|
#if 1 && (ACC_CC_GNUC >= 0x040100)
|
||||||
|
void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__));
|
||||||
|
#else
|
||||||
|
void __acc_cdecl_va addLoaderVA(const char *s, ...);
|
||||||
|
#endif
|
||||||
virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align);
|
virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align);
|
||||||
virtual int getSection(const char *sname, int *slen=NULL) const;
|
virtual int getSection(const char *sname, int *slen=NULL) const;
|
||||||
virtual int getSectionSize(const char *sname) const;
|
virtual int getSectionSize(const char *sname) const;
|
||||||
|
|||||||
@@ -553,23 +553,28 @@ static int do_option(int optc, const char *arg)
|
|||||||
|
|
||||||
// method
|
// method
|
||||||
case 702:
|
case 702:
|
||||||
|
opt->method_nrv2b_seen = true;
|
||||||
if (!set_method(M_NRV2B_LE32, -1))
|
if (!set_method(M_NRV2B_LE32, -1))
|
||||||
e_method(M_NRV2B_LE32, opt->level);
|
e_method(M_NRV2B_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
case 704:
|
case 704:
|
||||||
|
opt->method_nrv2d_seen = true;
|
||||||
if (!set_method(M_NRV2D_LE32, -1))
|
if (!set_method(M_NRV2D_LE32, -1))
|
||||||
e_method(M_NRV2D_LE32, opt->level);
|
e_method(M_NRV2D_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
case 705:
|
case 705:
|
||||||
|
opt->method_nrv2e_seen = true;
|
||||||
if (!set_method(M_NRV2E_LE32, -1))
|
if (!set_method(M_NRV2E_LE32, -1))
|
||||||
e_method(M_NRV2E_LE32, opt->level);
|
e_method(M_NRV2E_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
case 721:
|
case 721:
|
||||||
|
opt->method_lzma_seen = true;
|
||||||
opt->all_methods_use_lzma = true;
|
opt->all_methods_use_lzma = true;
|
||||||
if (!set_method(M_LZMA, -1))
|
if (!set_method(M_LZMA, -1))
|
||||||
e_method(M_LZMA, opt->level);
|
e_method(M_LZMA, opt->level);
|
||||||
break;
|
break;
|
||||||
case 722:
|
case 722:
|
||||||
|
opt->method_lzma_seen = false;
|
||||||
opt->all_methods_use_lzma = false;
|
opt->all_methods_use_lzma = false;
|
||||||
if (M_IS_LZMA(opt->method))
|
if (M_IS_LZMA(opt->method))
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
|
|||||||
+2
-2
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#ifndef __ACC_H_INCLUDED
|
#ifndef __ACC_H_INCLUDED
|
||||||
#define __ACC_H_INCLUDED 1
|
#define __ACC_H_INCLUDED 1
|
||||||
#define ACC_VERSION 20070112L
|
#define ACC_VERSION 20070113L
|
||||||
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
||||||
# define __CYGWIN__ __CYGWIN32__
|
# define __CYGWIN__ __CYGWIN32__
|
||||||
#endif
|
#endif
|
||||||
@@ -1302,7 +1302,7 @@ extern "C" {
|
|||||||
#elif !defined(ACC_ABI_BIG_ENDIAN) && !defined(ACC_ABI_LITTLE_ENDIAN)
|
#elif !defined(ACC_ABI_BIG_ENDIAN) && !defined(ACC_ABI_LITTLE_ENDIAN)
|
||||||
#if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
|
#if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
|
||||||
# define ACC_ABI_BIG_ENDIAN 1
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
#elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430)
|
#elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_BLACKFIN || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430)
|
||||||
# define ACC_ABI_LITTLE_ENDIAN 1
|
# define ACC_ABI_LITTLE_ENDIAN 1
|
||||||
#elif (ACC_ARCH_M68K || ACC_ARCH_S390)
|
#elif (ACC_ARCH_M68K || ACC_ARCH_S390)
|
||||||
# define ACC_ABI_BIG_ENDIAN 1
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ struct options_t {
|
|||||||
|
|
||||||
// compression options
|
// compression options
|
||||||
int method;
|
int method;
|
||||||
|
bool method_lzma_seen;
|
||||||
|
bool method_nrv2b_seen;
|
||||||
|
bool method_nrv2d_seen;
|
||||||
|
bool method_nrv2e_seen;
|
||||||
int level; // compression level 1..10
|
int level; // compression level 1..10
|
||||||
int filter; // preferred filter from Packer::getFilters()
|
int filter; // preferred filter from Packer::getFilters()
|
||||||
bool ultra_brute;
|
bool ultra_brute;
|
||||||
|
|||||||
+1
-1
@@ -632,7 +632,7 @@ void PackArmPe::pack(OutputFile *fo)
|
|||||||
|
|
||||||
//OutputFile::dump("x1", ibuf, usize);
|
//OutputFile::dump("x1", ibuf, usize);
|
||||||
|
|
||||||
// some checks for broken linkers - disable filter if neccessary
|
// some checks for broken linkers - disable filter if necessary
|
||||||
bool allow_filter = true;
|
bool allow_filter = true;
|
||||||
if (ih.codebase == ih.database
|
if (ih.codebase == ih.database
|
||||||
|| ih.codebase + ih.codesize > ih.imagesize
|
|| ih.codebase + ih.codesize > ih.imagesize
|
||||||
|
|||||||
+2
-1
@@ -76,10 +76,11 @@ const int *PackDjgpp2::getFilters() const
|
|||||||
|
|
||||||
|
|
||||||
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range,
|
unsigned range,
|
||||||
unsigned upper_limit) const
|
unsigned upper_limit) const
|
||||||
{
|
{
|
||||||
unsigned o = super::findOverlapOverhead(buf, range, upper_limit);
|
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
||||||
o = (o + 0x3ff) &~ 0x1ff;
|
o = (o + 0x3ff) &~ 0x1ff;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ protected:
|
|||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
|
|
||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual void buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Use the preprocessor to work around
|
// Use the preprocessor to work around
|
||||||
// - that the types embedding these enums have to be PODs, and
|
// - that the types embedding these enums have to be PODs, and
|
||||||
// deriving from an empty base class (which is the ususal C++ way
|
// deriving from an empty base class (which is the usual C++ way
|
||||||
// of "importing" enums) does not yield a POD any more
|
// of "importing" enums) does not yield a POD any more
|
||||||
// - that older compilers do not correctly perform EBCO
|
// - that older compilers do not correctly perform EBCO
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|||||||
+201
-58
@@ -53,24 +53,19 @@ PackExe::PackExe(InputFile *f) :
|
|||||||
bele = &N_BELE_RTP::le_policy;
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
|
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32);
|
||||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||||
|
stack_for_lzma = 0;
|
||||||
|
use_clear_dirty_stack = false;
|
||||||
|
|
||||||
|
// disable lzma for "--brute" unless explicitly given "--lzma"
|
||||||
|
if (opt->all_methods_use_lzma && !opt->method_lzma_seen)
|
||||||
|
opt->all_methods_use_lzma = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackExe::getCompressionMethods(int method, int level) const
|
const int *PackExe::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
static const int m_all[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_END };
|
|
||||||
static const int m_nrv2b[] = { M_NRV2B_8, M_END };
|
|
||||||
static const int m_nrv2d[] = { M_NRV2D_8, M_END };
|
|
||||||
static const int m_nrv2e[] = { M_NRV2E_8, M_END };
|
|
||||||
|
|
||||||
if (method == M_ALL) return m_all;
|
|
||||||
if (M_IS_NRV2B(method)) return m_nrv2b;
|
|
||||||
if (M_IS_NRV2D(method)) return m_nrv2d;
|
|
||||||
if (M_IS_NRV2E(method)) return m_nrv2e;
|
|
||||||
bool small = ih_imagesize <= 256*1024;
|
bool small = ih_imagesize <= 256*1024;
|
||||||
if (level == 1 || small)
|
return Packer::getDefaultCompressionMethods_8(method, level, small);
|
||||||
return m_nrv2b;
|
|
||||||
return m_nrv2e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -85,7 +80,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
#define oh (*eh)
|
#define oh (*eh)
|
||||||
// fill new exe header
|
// fill new exe header
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
if (!opt->dos_exe.no_reloc)
|
if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method))
|
||||||
flag |= USEJUMP;
|
flag |= USEJUMP;
|
||||||
if (ih.relocs == 0)
|
if (ih.relocs == 0)
|
||||||
flag |= NORELOC;
|
flag |= NORELOC;
|
||||||
@@ -94,7 +89,16 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
oh.ident = 'M' + 'Z' * 256;
|
oh.ident = 'M' + 'Z' * 256;
|
||||||
oh.headsize16 = 2;
|
oh.headsize16 = 2;
|
||||||
|
|
||||||
oh.sp = ih.sp > 0x200 ? (unsigned) ih.sp : 0x200;
|
unsigned minsp = 0x200;
|
||||||
|
if (M_IS_LZMA(ph.method))
|
||||||
|
minsp = stack_for_lzma;
|
||||||
|
minsp = ALIGN_UP(minsp, 16u);
|
||||||
|
assert(minsp < 0xff00);
|
||||||
|
if (oh.sp > minsp)
|
||||||
|
minsp = oh.sp;
|
||||||
|
if (minsp < 0xff00 - 2)
|
||||||
|
minsp = ALIGN_UP(minsp, 2u);
|
||||||
|
oh.sp = minsp;
|
||||||
|
|
||||||
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
|
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
|
||||||
oh.ss = ph.c_len/16 + destpara;
|
oh.ss = ph.c_len/16 + destpara;
|
||||||
@@ -106,27 +110,118 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
|
|
||||||
if (oh.ss != ih.ss)
|
if (oh.ss != ih.ss)
|
||||||
flag |= SS;
|
flag |= SS;
|
||||||
if (oh.sp != ih.sp)
|
if (oh.sp != ih.sp || M_IS_LZMA(ph.method))
|
||||||
flag |= SP;
|
flag |= SP;
|
||||||
return flag;
|
return flag;
|
||||||
#undef oh
|
#undef oh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackExe::addLoaderEpilogue(int flag)
|
||||||
|
{
|
||||||
|
addLoader("EXEMAIN5", NULL);
|
||||||
|
if (relocsize)
|
||||||
|
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
||||||
|
"EXERELO1",
|
||||||
|
has_9a ? "EXEREL9A" : "",
|
||||||
|
"EXERELO2",
|
||||||
|
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
|
||||||
|
"EXERELO3",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
addLoader("EXEMAIN8",
|
||||||
|
device_driver ? "DEVICEEND" : "",
|
||||||
|
(flag & SS) ? "EXESTACK" : "",
|
||||||
|
(flag & SP) ? "EXESTASP" : "",
|
||||||
|
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (!(flag & USEJUMP))
|
||||||
|
addLoader(ih.cs ? "EXERCSPO" : "",
|
||||||
|
"EXERETIP",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
linker->defineSymbol("original_cs", ih.cs);
|
||||||
|
linker->defineSymbol("original_ip", ih.ip);
|
||||||
|
linker->defineSymbol("original_sp", ih.sp);
|
||||||
|
linker->defineSymbol("original_ss", ih.ss);
|
||||||
|
linker->defineSymbol("reloc_size",
|
||||||
|
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
|
||||||
|
>= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||||
|
}
|
||||||
|
|
||||||
void PackExe::buildLoader(const Filter *)
|
void PackExe::buildLoader(const Filter *)
|
||||||
{
|
{
|
||||||
struct exe_header_t tmp_oh;
|
// get flag
|
||||||
int flag = fillExeHeader(&tmp_oh);
|
exe_header_t dummy_oh;
|
||||||
|
int flag = fillExeHeader(&dummy_oh);
|
||||||
|
|
||||||
// prepare loader
|
|
||||||
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
||||||
if (device_driver)
|
|
||||||
addLoader("DEVICEENTRY", NULL);
|
if (M_IS_LZMA(ph.method))
|
||||||
|
{
|
||||||
|
addLoader("LZMA_DEC00",
|
||||||
|
opt->small ? "LZMA_DEC10" : "LZMA_DEC20",
|
||||||
|
"LZMA_DEC30",
|
||||||
|
use_clear_dirty_stack ? "LZMA_DEC31" : "",
|
||||||
|
"LZMA_DEC32",
|
||||||
|
ph.u_len > 0xffff ? "LZMA_DEC33" : "",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
addLoaderEpilogue(flag);
|
||||||
|
defineDecompressorSymbols();
|
||||||
|
const unsigned lsize0 = getLoaderSize();
|
||||||
|
|
||||||
|
// Lzma decompression code starts at ss:0x10, and its size is
|
||||||
|
// lsize bytes. It also needs getDecompressorWrkmemSize() bytes
|
||||||
|
// during uncompression. It also uses some stack, so 0x100
|
||||||
|
// more bytes are allocated
|
||||||
|
stack_for_lzma = 0x10 + lsize0 + getDecompressorWrkmemSize() + 0x100;
|
||||||
|
stack_for_lzma = ALIGN_UP(stack_for_lzma, 16u);
|
||||||
|
|
||||||
|
unsigned clear_dirty_stack_low = 0x10 + lsize0;
|
||||||
|
clear_dirty_stack_low = ALIGN_UP(clear_dirty_stack_low, 2u);
|
||||||
|
if (use_clear_dirty_stack)
|
||||||
|
linker->defineSymbol("clear_dirty_stack_low", clear_dirty_stack_low);
|
||||||
|
|
||||||
|
relocateLoader();
|
||||||
|
const unsigned lsize = getLoaderSize();
|
||||||
|
assert(lsize0 == lsize);
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader, getLoader(), lsize);
|
||||||
|
|
||||||
|
MemBuffer compressed_lzma;
|
||||||
|
compressed_lzma.allocForCompression(lsize);
|
||||||
|
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
|
||||||
|
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma,
|
||||||
|
NULL, M_NRV2B_LE16, 9, NULL, NULL);
|
||||||
|
assert(r == UPX_E_OK); assert(c_len_lzma < lsize);
|
||||||
|
|
||||||
|
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
|
||||||
|
// reinit the loader
|
||||||
|
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
||||||
|
// prepare loader
|
||||||
|
if (device_driver)
|
||||||
|
addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", NULL);
|
||||||
|
|
||||||
|
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
|
||||||
|
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (device_driver)
|
||||||
|
addLoader("DEVICEENTRY,DEVICEENTRY2", NULL);
|
||||||
|
|
||||||
addLoader("EXEENTRY",
|
addLoader("EXEENTRY",
|
||||||
device_driver ? "DEVICESUB" : "EXESUB",
|
M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
|
||||||
"JNCDOCOPY",
|
"JNCDOCOPY",
|
||||||
relocsize ? "EXERELPU" : "",
|
relocsize ? "EXERELPU" : "",
|
||||||
"EXEMAIN4,+G5DXXXX,UPX1HEAD,EXECUTPO",
|
"EXEMAIN4",
|
||||||
|
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B",
|
||||||
|
"EXEMAIN4C",
|
||||||
|
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
|
||||||
|
"+G5DXXXX,UPX1HEAD,EXECUTPO",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (ph.method == M_NRV2B_8)
|
if (ph.method == M_NRV2B_8)
|
||||||
@@ -165,30 +260,12 @@ void PackExe::buildLoader(const Filter *)
|
|||||||
"NRV2EEX9",
|
"NRV2EEX9",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
else if M_IS_LZMA(ph.method)
|
||||||
|
return;
|
||||||
else
|
else
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
addLoader("EXEMAIN5", NULL);
|
|
||||||
if (relocsize)
|
addLoaderEpilogue(flag);
|
||||||
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
|
||||||
"EXERELO1",
|
|
||||||
has_9a ? "EXEREL9A" : "",
|
|
||||||
"EXERELO2",
|
|
||||||
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
|
|
||||||
"EXERELO3",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
addLoader("EXEMAIN8",
|
|
||||||
device_driver ? "DEVICEEND" : "",
|
|
||||||
(flag & SS) ? "EXESTACK" : "",
|
|
||||||
(flag & SP) ? "EXESTASP" : "",
|
|
||||||
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (!(flag & USEJUMP))
|
|
||||||
addLoader(ih.cs ? "EXERCSPO" : "",
|
|
||||||
"EXERETIP",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -324,7 +401,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
unsigned offs = addr - es*16;
|
unsigned offs = addr - es*16;
|
||||||
if (offs >= 3 && b[es*16 + offs-3] == 0x9a)
|
if (offs >= 3 && b[es*16 + offs-3] == 0x9a && offs > di + 3)
|
||||||
{
|
{
|
||||||
for (t = di; t < offs-3; t++)
|
for (t = di; t < offs-3; t++)
|
||||||
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
|
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
|
||||||
@@ -429,9 +506,12 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
// compress (max_match = 8192)
|
// compress (max_match = 8192)
|
||||||
upx_compress_config_t cconf; cconf.reset();
|
upx_compress_config_t cconf; cconf.reset();
|
||||||
cconf.conf_ucl.max_match = MAXMATCH;
|
cconf.conf_ucl.max_match = MAXMATCH;
|
||||||
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||||
compressWithFilters(&ft, 32, &cconf);
|
compressWithFilters(&ft, 32, &cconf);
|
||||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
|
||||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||||
|
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||||
|
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||||
|
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
if (opt->debug.debug_level)
|
if (opt->debug.debug_level)
|
||||||
@@ -497,15 +577,13 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
extra_info[eisize++] = (unsigned char) flag;
|
extra_info[eisize++] = (unsigned char) flag;
|
||||||
|
|
||||||
linker->defineSymbol("original_cs", ih.cs);
|
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||||
linker->defineSymbol("original_ip", ih.ip);
|
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
|
||||||
linker->defineSymbol("original_sp", ih.sp);
|
|
||||||
linker->defineSymbol("original_ss", ih.ss);
|
unsigned decompressor_entry = 1 + (packedsize & 15);
|
||||||
linker->defineSymbol("reloc_size",
|
if (M_IS_LZMA(ph.method))
|
||||||
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
|
decompressor_entry = 0x10;
|
||||||
>= relocsize ? 0 : MAXRELOCS) - relocsize);
|
linker->defineSymbol("decompressor_entry", decompressor_entry);
|
||||||
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)
|
||||||
@@ -541,8 +619,10 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
oh.m512 = outputlen & 511;
|
oh.m512 = outputlen & 511;
|
||||||
oh.p512 = (outputlen + 511) >> 9;
|
oh.p512 = (outputlen + 511) >> 9;
|
||||||
|
|
||||||
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0;
|
const char *exeentry = M_IS_LZMA(ph.method) ? "LZMAENTRY" : "EXEENTRY";
|
||||||
|
oh.ip = device_driver ? getLoaderSection(exeentry) - 2 : 0;
|
||||||
|
|
||||||
|
defineDecompressorSymbols();
|
||||||
relocateLoader();
|
relocateLoader();
|
||||||
memcpy(loader, getLoader(), lsize);
|
memcpy(loader, getLoader(), lsize);
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader,e_len);
|
||||||
@@ -591,7 +671,7 @@ int PackExe::canUnpack()
|
|||||||
return false;
|
return false;
|
||||||
const off_t off = ih.headsize16 * 16;
|
const off_t off = ih.headsize16 * 16;
|
||||||
fi->seek(off, SEEK_SET);
|
fi->seek(off, SEEK_SET);
|
||||||
bool b = readPackHeader(256);
|
bool b = readPackHeader(4096);
|
||||||
return b && (off + (off_t) ph.c_len <= file_size);
|
return b && (off + (off_t) ph.c_len <= file_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,6 +806,69 @@ Linker* PackExe::newLinker() const
|
|||||||
return new ElfLinkerX86();
|
return new ElfLinkerX86();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
memory layout at decompression time
|
||||||
|
===================================
|
||||||
|
|
||||||
|
normal exe
|
||||||
|
----------
|
||||||
|
|
||||||
|
a, at load time
|
||||||
|
|
||||||
|
(e - copying code, C - compressed data, d - decompressor+relocator,
|
||||||
|
x - not specified, U - uncompressed code+data, R uncompressed relocation)
|
||||||
|
|
||||||
|
eeCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
|
||||||
|
^ CS:0 ^ SS:0
|
||||||
|
|
||||||
|
b, after copying
|
||||||
|
|
||||||
|
xxxxxxxxxxxxxxxCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCdddd
|
||||||
|
^ES:DI=0 ^ DS:SI=0 ^ CS=SS, IP in range 0..0xf
|
||||||
|
|
||||||
|
c, after uncompression
|
||||||
|
|
||||||
|
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUURRdddd
|
||||||
|
^ ES:DI
|
||||||
|
|
||||||
|
device driver
|
||||||
|
-------------
|
||||||
|
|
||||||
|
the file has 2 entry points, CS:0 in device driver mode, and
|
||||||
|
CS:exe_as_device_entry in normal mode. the code in section DEVICEENTRY
|
||||||
|
sets up the same environment for section EXEENTRY, as it would see in normal
|
||||||
|
execution mode.
|
||||||
|
|
||||||
|
lzma uncompression for normal exes
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
(n - nrv2b uncompressor, l - nrv2b compressed lzma + relocator code)
|
||||||
|
|
||||||
|
a, at load time
|
||||||
|
|
||||||
|
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC
|
||||||
|
|
||||||
|
^ CS:0 ^ SS:0
|
||||||
|
|
||||||
|
b, after nrv2b
|
||||||
|
|
||||||
|
nneelllCCCCCCCCCCCCCCCCCCCCCCCCC dddd
|
||||||
|
^ CS:0 ^ SS:0x10
|
||||||
|
|
||||||
|
after this, normal ee code runs
|
||||||
|
|
||||||
|
lzma + device driver
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
(D - device driver adapter)
|
||||||
|
|
||||||
|
a, at load time
|
||||||
|
|
||||||
|
DDnneelllCCCCCCCCCCCCCCCCCCCCCCCCC
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ protected:
|
|||||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||||
virtual void buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual Linker* newLinker() const;
|
virtual Linker* newLinker() const;
|
||||||
|
void addLoaderEpilogue(int flag);
|
||||||
|
|
||||||
struct exe_header_t
|
struct exe_header_t
|
||||||
{
|
{
|
||||||
@@ -110,6 +111,9 @@ protected:
|
|||||||
MINMEM = 16,
|
MINMEM = 16,
|
||||||
MAXMEM = 32
|
MAXMEM = 32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned stack_for_lzma; // stack size required for lzma
|
||||||
|
bool use_clear_dirty_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -416,8 +416,8 @@ class PackLinuxElf32armLe : public PackLinuxElf32Le
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf32armLe(InputFile *f);
|
PackLinuxElf32armLe(InputFile *f);
|
||||||
virtual ~PackLinuxElf32armLe();
|
virtual ~PackLinuxElf32armLe();
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEL; }
|
||||||
virtual const char *getName() const { return "linux/armLE"; }
|
virtual const char *getName() const { return "linux/armel"; }
|
||||||
virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; }
|
virtual const char *getFullName(const options_t *) const { return "arm-linux.elf"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
@@ -436,8 +436,8 @@ class PackLinuxElf32armBe : public PackLinuxElf32Be
|
|||||||
public:
|
public:
|
||||||
PackLinuxElf32armBe(InputFile *f);
|
PackLinuxElf32armBe(InputFile *f);
|
||||||
virtual ~PackLinuxElf32armBe();
|
virtual ~PackLinuxElf32armBe();
|
||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMEB; }
|
||||||
virtual const char *getName() const { return "linux/armBE"; }
|
virtual const char *getName() const { return "linux/armeb"; }
|
||||||
virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; }
|
virtual const char *getFullName(const options_t *) const { return "armeb-linux.elf"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
|||||||
+416
-51
@@ -39,22 +39,34 @@ static const
|
|||||||
static const
|
static const
|
||||||
#include "stub/powerpc-darwin.macho-fold.h"
|
#include "stub/powerpc-darwin.macho-fold.h"
|
||||||
|
|
||||||
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
static const
|
||||||
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
#include "stub/i386-darwin.macho-entry.h"
|
||||||
|
static const
|
||||||
|
#include "stub/i386-darwin.macho-fold.h"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor,
|
||||||
|
unsigned count, unsigned size) :
|
||||||
|
super(f), my_cputype(cputype), my_thread_flavor(flavor),
|
||||||
|
my_thread_state_word_count(count), my_thread_command_size(size),
|
||||||
|
n_segment(0), rawmseg(NULL), msegcmd(NULL)
|
||||||
{
|
{
|
||||||
|
MachClass::compileTimeAssertions();
|
||||||
|
bele = N_BELE_CTP::getRTP<BeLePolicy>();
|
||||||
}
|
}
|
||||||
|
|
||||||
PackMachPPC32::~PackMachPPC32()
|
template <class T>
|
||||||
|
PackMachBase<T>::~PackMachBase()
|
||||||
{
|
{
|
||||||
delete [] msegcmd;
|
|
||||||
delete [] rawmseg;
|
delete [] rawmseg;
|
||||||
|
delete [] msegcmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) const
|
template <class T>
|
||||||
|
const int *PackMachBase<T>::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
// There really is no LE bias in M_NRV2E_LE32.
|
// There really is no LE bias.
|
||||||
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
|
return Packer::getDefaultCompressionMethods_le32(method, level);
|
||||||
return m_nrv2e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -64,13 +76,25 @@ const int *PackMachPPC32::getFilters() const
|
|||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int const *PackMachI386::getFilters() const
|
||||||
|
{
|
||||||
|
static const int filters[] = { 0x49, FT_END };
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
|
||||||
Linker *PackMachPPC32::newLinker() const
|
Linker *PackMachPPC32::newLinker() const
|
||||||
{
|
{
|
||||||
return new ElfLinkerPpc32;
|
return new ElfLinkerPpc32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackMachI386::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
void
|
void
|
||||||
PackMachPPC32::addStubEntrySections(Filter const *)
|
PackMachBase<T>::addStubEntrySections(Filter const *)
|
||||||
{
|
{
|
||||||
addLoader("MACOS000", NULL);
|
addLoader("MACOS000", NULL);
|
||||||
//addLoader(getDecompressorSections(), NULL);
|
//addLoader(getDecompressorSections(), NULL);
|
||||||
@@ -83,15 +107,79 @@ PackMachPPC32::addStubEntrySections(Filter const *)
|
|||||||
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
|
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackMachI386::addStubEntrySections(Filter const *ft)
|
||||||
|
{
|
||||||
|
int const n_mru = ft->n_mru; // FIXME: belongs to filter? packerf?
|
||||||
|
|
||||||
void PackMachPPC32::defineSymbols(Filter const *)
|
// entry to stub
|
||||||
|
addLoader("LEXEC000", NULL);
|
||||||
|
|
||||||
|
if (ft->id) {
|
||||||
|
{ // decompr, unfilter are separate
|
||||||
|
addLoader("LXUNF000", NULL);
|
||||||
|
addLoader("LXUNF002", NULL);
|
||||||
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
|
if (256==n_mru) {
|
||||||
|
addLoader("MRUBYTE0", NULL);
|
||||||
|
}
|
||||||
|
else if (n_mru) {
|
||||||
|
addLoader("LXMRU005", NULL);
|
||||||
|
}
|
||||||
|
if (n_mru) {
|
||||||
|
addLoader("LXMRU006", NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addLoader("LXMRU007", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0x40==(ft->id & 0xF0)) {
|
||||||
|
addLoader("LXUNF008", NULL);
|
||||||
|
}
|
||||||
|
addLoader("LXUNF010", NULL);
|
||||||
|
}
|
||||||
|
if (n_mru) {
|
||||||
|
addLoader("LEXEC009", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addLoader("LEXEC010", NULL);
|
||||||
|
addLoader(getDecompressorSections(), NULL);
|
||||||
|
addLoader("LEXEC015", NULL);
|
||||||
|
if (ft->id) {
|
||||||
|
{ // decompr, unfilter are separate
|
||||||
|
if (0x80!=(ft->id & 0xF0)) {
|
||||||
|
addLoader("LXUNF042", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addFilter32(ft->id);
|
||||||
|
{ // decompr, unfilter are separate
|
||||||
|
if (0x80==(ft->id & 0xF0)) {
|
||||||
|
if (0==n_mru) {
|
||||||
|
addLoader("LXMRU058", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addLoader("LXUNF035", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addLoader("LEXEC017", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
addLoader("IDENTSTR", NULL);
|
||||||
|
addLoader("LEXEC020", NULL);
|
||||||
|
addLoader("FOLDEXEC", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PackMachBase<T>::defineSymbols(Filter const *)
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
void
|
void
|
||||||
PackMachPPC32::buildMachLoader(
|
PackMachBase<T>::buildMachLoader(
|
||||||
upx_byte const *const proto,
|
upx_byte const *const proto,
|
||||||
unsigned const szproto,
|
unsigned const szproto,
|
||||||
upx_byte const *const fold,
|
upx_byte const *const fold,
|
||||||
@@ -142,11 +230,23 @@ PackMachPPC32::buildLoader(const Filter *ft)
|
|||||||
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
|
stub_powerpc_darwin_macho_entry, sizeof(stub_powerpc_darwin_macho_entry),
|
||||||
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
|
stub_powerpc_darwin_macho_fold, sizeof(stub_powerpc_darwin_macho_fold), ft );
|
||||||
}
|
}
|
||||||
void PackMachPPC32::patchLoader() { }
|
|
||||||
void PackMachPPC32::updateLoader(OutputFile *) {}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PackMachPPC32::patchLoaderChecksum()
|
PackMachI386::buildLoader(const Filter *ft)
|
||||||
|
{
|
||||||
|
buildMachLoader(
|
||||||
|
stub_i386_darwin_macho_entry, sizeof(stub_i386_darwin_macho_entry),
|
||||||
|
stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PackMachBase<T>::patchLoader() { }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PackMachBase<T>::updateLoader(OutputFile *) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PackMachBase<T>::patchLoaderChecksum()
|
||||||
{
|
{
|
||||||
unsigned char *const ptr = getLoader();
|
unsigned char *const ptr = getLoader();
|
||||||
l_info *const lp = &linfo;
|
l_info *const lp = &linfo;
|
||||||
@@ -160,8 +260,9 @@ PackMachPPC32::patchLoaderChecksum()
|
|||||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __acc_cdecl_qsort
|
template <class T>
|
||||||
compare_segment_command(void const *const aa, void const *const bb)
|
int __acc_cdecl_qsort
|
||||||
|
PackMachBase<T>::compare_segment_command(void const *const aa, void const *const bb)
|
||||||
{
|
{
|
||||||
Mach_segment_command const *const a = (Mach_segment_command const *)aa;
|
Mach_segment_command const *const a = (Mach_segment_command const *)aa;
|
||||||
Mach_segment_command const *const b = (Mach_segment_command const *)bb;
|
Mach_segment_command const *const b = (Mach_segment_command const *)bb;
|
||||||
@@ -174,8 +275,7 @@ compare_segment_command(void const *const aa, void const *const bb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||||
PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|
||||||
{
|
{
|
||||||
// offset of p_info in compressed file
|
// offset of p_info in compressed file
|
||||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||||
@@ -184,31 +284,59 @@ PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
|||||||
segcmdo.filesize = fo->getBytesWritten();
|
segcmdo.filesize = fo->getBytesWritten();
|
||||||
segcmdo.vmsize += segcmdo.filesize;
|
segcmdo.vmsize += segcmdo.filesize;
|
||||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||||
fo->write(&segcmdo, sizeof(segcmdo));
|
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||||
fo->write(&threado, sizeof(threado));
|
fo->rewrite(&threado, sizeof(threado));
|
||||||
fo->write(&linfo, sizeof(linfo));
|
fo->rewrite(&linfo, sizeof(linfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||||
PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
{
|
||||||
|
// offset of p_info in compressed file
|
||||||
|
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||||
|
|
||||||
|
super::pack4(fo, ft);
|
||||||
|
segcmdo.filesize = fo->getBytesWritten();
|
||||||
|
segcmdo.vmsize += segcmdo.filesize;
|
||||||
|
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||||
|
fo->rewrite(&segcmdo, sizeof(segcmdo));
|
||||||
|
fo->rewrite(&threado, sizeof(threado));
|
||||||
|
fo->rewrite(&linfo, sizeof(linfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||||
{
|
{
|
||||||
BE32 disp;
|
BE32 disp;
|
||||||
unsigned const zero = 0;
|
unsigned const zero = 0;
|
||||||
unsigned len = fo->getBytesWritten();
|
unsigned len = fo->getBytesWritten();
|
||||||
fo->write(&zero, 3& (0u-len));
|
fo->write(&zero, 3& (0u-len));
|
||||||
len += (3& (0u-len)) + sizeof(disp);
|
len += (3& (0u-len)) + sizeof(disp);
|
||||||
set_be32(&disp, 4+ len - sz_mach_headers); // 4: sizeof(instruction)
|
disp = 4+ len - sz_mach_headers; // 4: sizeof(instruction)
|
||||||
fo->write(&disp, sizeof(disp));
|
fo->write(&disp, sizeof(disp));
|
||||||
|
|
||||||
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
|
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
|
||||||
super::pack3(fo, ft);
|
super::pack3(fo, ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||||
|
{
|
||||||
|
LE32 disp;
|
||||||
|
unsigned const zero = 0;
|
||||||
|
unsigned len = fo->getBytesWritten();
|
||||||
|
fo->write(&zero, 3& (0u-len));
|
||||||
|
len += (3& (0u-len));
|
||||||
|
disp = len - sz_mach_headers;
|
||||||
|
fo->write(&disp, sizeof(disp));
|
||||||
|
|
||||||
|
threado.state.eip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
|
||||||
|
super::pack3(fo, ft);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD
|
// Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD
|
||||||
// which follows in the file (or end-of-file). Optimize for common case
|
// which follows in the file (or end-of-file). Optimize for common case
|
||||||
// where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap.
|
// where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap.
|
||||||
|
|
||||||
unsigned PackMachPPC32::find_SEGMENT_gap(
|
template <class T>
|
||||||
|
unsigned PackMachBase<T>::find_SEGMENT_gap(
|
||||||
unsigned const k
|
unsigned const k
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -216,8 +344,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|
|||||||
|| 0==msegcmd[k].filesize ) {
|
|| 0==msegcmd[k].filesize ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned const hi = get_native32(&msegcmd[k].fileoff) +
|
unsigned const hi = msegcmd[k].fileoff + msegcmd[k].filesize;
|
||||||
get_native32(&msegcmd[k].filesize);
|
|
||||||
unsigned lo = ph.u_file_size;
|
unsigned lo = ph.u_file_size;
|
||||||
unsigned j = k;
|
unsigned j = k;
|
||||||
for (;;) { // circular search, optimize for adjacent ascending
|
for (;;) { // circular search, optimize for adjacent ascending
|
||||||
@@ -230,7 +357,7 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|
|||||||
}
|
}
|
||||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd
|
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd
|
||||||
&& 0!=msegcmd[j].filesize ) {
|
&& 0!=msegcmd[j].filesize ) {
|
||||||
unsigned const t = get_native32(&msegcmd[j].fileoff);
|
unsigned const t = msegcmd[j].fileoff;
|
||||||
if ((t - hi) < (lo - hi)) {
|
if ((t - hi) < (lo - hi)) {
|
||||||
lo = t;
|
lo = t;
|
||||||
if (hi==lo) {
|
if (hi==lo) {
|
||||||
@@ -242,8 +369,20 @@ unsigned PackMachPPC32::find_SEGMENT_gap(
|
|||||||
return lo - hi;
|
return lo - hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template <class T>
|
||||||
PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
void PackMachBase<T>::pack4(OutputFile *fo, Filter &ft)
|
||||||
|
{
|
||||||
|
PackUnix::pack4(fo, ft); // FIXME super() does not work?
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft)
|
||||||
|
{
|
||||||
|
PackUnix::pack3(fo, ft); // FIXME super() does not work?
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||||
{
|
{
|
||||||
Extent x;
|
Extent x;
|
||||||
unsigned k;
|
unsigned k;
|
||||||
@@ -269,6 +408,17 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
uip->ui_pass = 0;
|
uip->ui_pass = 0;
|
||||||
ft.addvalue = 0;
|
ft.addvalue = 0;
|
||||||
|
|
||||||
|
// Packer::compressWithFilters chooses a filter for us, and the stubs
|
||||||
|
// can handle only one filter, and most filters are for executable
|
||||||
|
// instructions. So filter only the largest executable segment.
|
||||||
|
unsigned exe_filesize_max = 0;
|
||||||
|
for (k = 0; k < n_segment; ++k)
|
||||||
|
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||||
|
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||||
|
&& exe_filesize_max < msegcmd[k].filesize) {
|
||||||
|
exe_filesize_max = msegcmd[k].filesize;
|
||||||
|
}
|
||||||
|
|
||||||
int nx = 0;
|
int nx = 0;
|
||||||
for (k = 0; k < n_segment; ++k)
|
for (k = 0; k < n_segment; ++k)
|
||||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||||
@@ -280,17 +430,20 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
x.offset += delta;
|
x.offset += delta;
|
||||||
x.size -= delta;
|
x.size -= delta;
|
||||||
}
|
}
|
||||||
|
bool const do_filter = (msegcmd[k].filesize==exe_filesize_max)
|
||||||
|
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot);
|
||||||
packExtent(x, total_in, total_out,
|
packExtent(x, total_in, total_out,
|
||||||
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
(do_filter ? &ft : 0 ), fo, hdr_u_len );
|
||||||
? &ft : 0 ), fo, hdr_u_len );
|
if (do_filter) {
|
||||||
|
exe_filesize_max = 0;
|
||||||
|
}
|
||||||
hdr_u_len = 0;
|
hdr_u_len = 0;
|
||||||
++nx;
|
++nx;
|
||||||
}
|
}
|
||||||
for (k = 0; k < n_segment; ++k) {
|
for (k = 0; k < n_segment; ++k) {
|
||||||
x.size = find_SEGMENT_gap(k);
|
x.size = find_SEGMENT_gap(k);
|
||||||
if (x.size) {
|
if (x.size) {
|
||||||
x.offset = get_native32(&msegcmd[k].fileoff) +
|
x.offset = msegcmd[k].fileoff +msegcmd[k].filesize;
|
||||||
get_native32(&msegcmd[k].filesize);
|
|
||||||
packExtent(x, total_in, total_out, 0, fo);
|
packExtent(x, total_in, total_out, 0, fo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,12 +457,33 @@ PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
|||||||
#undef PAGE_SIZE
|
#undef PAGE_SIZE
|
||||||
#define PAGE_MASK (~0u<<12)
|
#define PAGE_MASK (~0u<<12)
|
||||||
#define PAGE_SIZE -PAGE_MASK
|
#define PAGE_SIZE -PAGE_MASK
|
||||||
void
|
|
||||||
PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable header
|
void PackMachPPC32::pack1_setup_threado(OutputFile *const fo)
|
||||||
|
{
|
||||||
|
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
||||||
|
threado.cmdsize = sizeof(threado);
|
||||||
|
threado.flavor = my_thread_flavor;
|
||||||
|
threado.count = my_thread_state_word_count;
|
||||||
|
memset(&threado.state, 0, sizeof(threado.state));
|
||||||
|
fo->write(&threado, sizeof(threado));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackMachI386::pack1_setup_threado(OutputFile *const fo)
|
||||||
|
{
|
||||||
|
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
||||||
|
threado.cmdsize = sizeof(threado);
|
||||||
|
threado.flavor = my_thread_flavor;
|
||||||
|
threado.count = my_thread_state_word_count;
|
||||||
|
memset(&threado.state, 0, sizeof(threado.state));
|
||||||
|
fo->write(&threado, sizeof(threado));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header
|
||||||
{
|
{
|
||||||
mhdro = mhdri;
|
mhdro = mhdri;
|
||||||
mhdro.ncmds = 2;
|
mhdro.ncmds = 2;
|
||||||
mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado);
|
mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size;
|
||||||
mhdro.flags = Mach_header::MH_NOUNDEFS;
|
mhdro.flags = Mach_header::MH_NOUNDEFS;
|
||||||
fo->write(&mhdro, sizeof(mhdro));
|
fo->write(&mhdro, sizeof(mhdro));
|
||||||
|
|
||||||
@@ -329,12 +503,7 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
|
|||||||
segcmdo.flags = 0;
|
segcmdo.flags = 0;
|
||||||
fo->write(&segcmdo, sizeof(segcmdo));
|
fo->write(&segcmdo, sizeof(segcmdo));
|
||||||
|
|
||||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
pack1_setup_threado(fo);
|
||||||
threado.cmdsize = sizeof(threado);
|
|
||||||
threado.flavor = Mach_thread_command::PPC_THREAD_STATE;
|
|
||||||
threado.count = Mach_thread_command::PPC_THREAD_STATE_COUNT;
|
|
||||||
memset(&threado.state, 0, sizeof(threado.state));
|
|
||||||
fo->write(&threado, sizeof(threado));
|
|
||||||
sz_mach_headers = fo->getBytesWritten();
|
sz_mach_headers = fo->getBytesWritten();
|
||||||
|
|
||||||
memset((char *)&linfo, 0, sizeof(linfo));
|
memset((char *)&linfo, 0, sizeof(linfo));
|
||||||
@@ -343,9 +512,11 @@ PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable hea
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template <class T>
|
||||||
PackMachPPC32::unpack(OutputFile *fo)
|
void PackMachBase<T>::unpack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
|
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) +
|
||||||
|
my_thread_command_size + sizeof(linfo);
|
||||||
fi->seek(overlay_offset, SEEK_SET);
|
fi->seek(overlay_offset, SEEK_SET);
|
||||||
p_info hbuf;
|
p_info hbuf;
|
||||||
fi->readx(&hbuf, sizeof(hbuf));
|
fi->readx(&hbuf, sizeof(hbuf));
|
||||||
@@ -359,6 +530,8 @@ PackMachPPC32::unpack(OutputFile *fo)
|
|||||||
fi->readx(&bhdr, sizeof(bhdr));
|
fi->readx(&bhdr, sizeof(bhdr));
|
||||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||||
|
ph.method = bhdr.b_method;
|
||||||
|
ph.filter = bhdr.b_ftid;
|
||||||
ph.filter_cto = bhdr.b_cto8;
|
ph.filter_cto = bhdr.b_cto8;
|
||||||
|
|
||||||
// Uncompress Macho headers
|
// Uncompress Macho headers
|
||||||
@@ -396,15 +569,14 @@ PackMachPPC32::unpack(OutputFile *fo)
|
|||||||
) {
|
) {
|
||||||
if (Mach_segment_command::LC_SEGMENT==sc->cmd
|
if (Mach_segment_command::LC_SEGMENT==sc->cmd
|
||||||
&& 0!=sc->filesize ) {
|
&& 0!=sc->filesize ) {
|
||||||
unsigned filesize = get_be32(&sc->filesize);
|
unsigned filesize = sc->filesize;
|
||||||
unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
|
unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned j = 0; j < ncmds; ++j) {
|
for (unsigned j = 0; j < ncmds; ++j) {
|
||||||
unsigned const size = find_SEGMENT_gap(j);
|
unsigned const size = find_SEGMENT_gap(j);
|
||||||
if (size) {
|
if (size) {
|
||||||
unsigned const where = get_native32(&msegcmd[k].fileoff) +
|
unsigned const where = msegcmd[k].fileoff +msegcmd[k].filesize;
|
||||||
get_native32(&msegcmd[k].filesize);
|
|
||||||
if (fo)
|
if (fo)
|
||||||
fo->seek(where, SEEK_SET);
|
fo->seek(where, SEEK_SET);
|
||||||
unpackExtent(size, fo, total_in, total_out,
|
unpackExtent(size, fo, total_in, total_out,
|
||||||
@@ -414,14 +586,14 @@ PackMachPPC32::unpack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
template <class T>
|
||||||
PackMachPPC32::canPack()
|
bool PackMachBase<T>::canPack()
|
||||||
{
|
{
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&mhdri, sizeof(mhdri));
|
fi->readx(&mhdri, sizeof(mhdri));
|
||||||
|
|
||||||
if (Mach_header::MH_MAGIC !=mhdri.magic
|
if (Mach_header::MH_MAGIC !=mhdri.magic
|
||||||
|| Mach_header::CPU_TYPE_POWERPC !=mhdri.cputype
|
|| my_cputype !=mhdri.cputype
|
||||||
|| Mach_header::MH_EXECUTE !=mhdri.filetype
|
|| Mach_header::MH_EXECUTE !=mhdri.filetype
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
@@ -457,11 +629,204 @@ PackMachPPC32::canPack()
|
|||||||
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
|
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// info: currently the header is 36 (32+4) bytes before EOF
|
||||||
|
unsigned char buf[256];
|
||||||
|
fi->seek(-(off_t)sizeof(buf), SEEK_END);
|
||||||
|
fi->readx(buf, sizeof(buf));
|
||||||
|
checkAlreadyPacked(buf, sizeof(buf));
|
||||||
|
|
||||||
// set options
|
// set options
|
||||||
opt->o_unix.blocksize = file_size;
|
opt->o_unix.blocksize = file_size;
|
||||||
return 0 < n_segment;
|
return 0 < n_segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template class PackMachBase<MachClass_BE32>;
|
||||||
|
template class PackMachBase<MachClass_LE32>;
|
||||||
|
|
||||||
|
|
||||||
|
PackMachFat::PackMachFat(InputFile *f) : super(f)
|
||||||
|
{
|
||||||
|
bele = &N_BELE_RTP::le_policy; // sham
|
||||||
|
}
|
||||||
|
|
||||||
|
PackMachFat::~PackMachFat()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const int *PackMachFat::getCompressionMethods(int /*method*/, int /*level*/) const
|
||||||
|
{
|
||||||
|
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
|
||||||
|
return m_nrv2e; // sham
|
||||||
|
}
|
||||||
|
|
||||||
|
const int *PackMachFat::getFilters() const
|
||||||
|
{
|
||||||
|
static const int filters[] = { 0x49, FT_END };
|
||||||
|
return filters; // sham
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackMachFat::pack(OutputFile *fo)
|
||||||
|
{
|
||||||
|
unsigned const in_size = this->file_size;
|
||||||
|
fo->write(&fat_head, sizeof(fat_head.fat) +
|
||||||
|
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||||
|
unsigned length = 0;
|
||||||
|
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||||
|
unsigned base = fo->unset_extent(); // actual length
|
||||||
|
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
|
||||||
|
fo->seek(base, SEEK_SET);
|
||||||
|
fo->set_extent(base, ~0u);
|
||||||
|
|
||||||
|
ph.u_file_size = fat_head.arch[j].size;
|
||||||
|
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||||
|
switch (fat_head.arch[j].cputype) {
|
||||||
|
case PackMachFat::CPU_TYPE_I386: {
|
||||||
|
PackMachI386 packer(fi);
|
||||||
|
packer.initPackHeader();
|
||||||
|
packer.canPack();
|
||||||
|
packer.updatePackHeader();
|
||||||
|
packer.pack(fo);
|
||||||
|
} break;
|
||||||
|
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||||
|
PackMachPPC32 packer(fi);
|
||||||
|
packer.initPackHeader();
|
||||||
|
packer.canPack();
|
||||||
|
packer.updatePackHeader();
|
||||||
|
packer.pack(fo);
|
||||||
|
} break;
|
||||||
|
} // switch cputype
|
||||||
|
fat_head.arch[j].offset = base;
|
||||||
|
length = fo->unset_extent();
|
||||||
|
fat_head.arch[j].size = length - base;
|
||||||
|
}
|
||||||
|
ph.u_file_size = in_size;
|
||||||
|
fi->set_extent(0, in_size);
|
||||||
|
|
||||||
|
fo->seek(0, SEEK_SET);
|
||||||
|
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
|
||||||
|
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||||
|
fo->set_extent(0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackMachFat::unpack(OutputFile *fo)
|
||||||
|
{
|
||||||
|
fo->seek(0, SEEK_SET);
|
||||||
|
fo->write(&fat_head, sizeof(fat_head.fat) +
|
||||||
|
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||||
|
unsigned length;
|
||||||
|
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||||
|
unsigned base = fo->unset_extent(); // actual length
|
||||||
|
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
|
||||||
|
fo->seek(base, SEEK_SET);
|
||||||
|
fo->set_extent(base, ~0u);
|
||||||
|
|
||||||
|
ph.u_file_size = fat_head.arch[j].size;
|
||||||
|
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||||
|
switch (fat_head.arch[j].cputype) {
|
||||||
|
case PackMachFat::CPU_TYPE_I386: {
|
||||||
|
PackMachI386 packer(fi);
|
||||||
|
packer.initPackHeader();
|
||||||
|
packer.canUnpack();
|
||||||
|
packer.unpack(fo);
|
||||||
|
} break;
|
||||||
|
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||||
|
PackMachPPC32 packer(fi);
|
||||||
|
packer.initPackHeader();
|
||||||
|
packer.canUnpack();
|
||||||
|
packer.unpack(fo);
|
||||||
|
} break;
|
||||||
|
} // switch cputype
|
||||||
|
fat_head.arch[j].offset = base;
|
||||||
|
length = fo->unset_extent();
|
||||||
|
fat_head.arch[j].size = length - base;
|
||||||
|
}
|
||||||
|
fo->unset_extent();
|
||||||
|
fo->seek(0, SEEK_SET);
|
||||||
|
fo->rewrite(&fat_head, sizeof(fat_head.fat) +
|
||||||
|
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PackMachFat::canPack()
|
||||||
|
{
|
||||||
|
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
||||||
|
|
||||||
|
fi->readx(&fat_head, sizeof(fat_head));
|
||||||
|
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|
||||||
|
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||||
|
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||||
|
switch (arch[j].cputype) {
|
||||||
|
default: return false;
|
||||||
|
case PackMachFat::CPU_TYPE_I386: {
|
||||||
|
PackMachI386 packer(fi);
|
||||||
|
if (!packer.canPack())
|
||||||
|
return false;
|
||||||
|
} break;
|
||||||
|
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||||
|
PackMachPPC32 packer(fi);
|
||||||
|
if (!packer.canPack())
|
||||||
|
return false;
|
||||||
|
} break;
|
||||||
|
} // switch cputype
|
||||||
|
}
|
||||||
|
|
||||||
|
// info: currently the header is 36 (32+4) bytes before EOF
|
||||||
|
unsigned char buf[256];
|
||||||
|
fi->seek(-(off_t)sizeof(buf), SEEK_END);
|
||||||
|
fi->readx(buf, sizeof(buf));
|
||||||
|
checkAlreadyPacked(buf, sizeof(buf));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PackMachFat::canUnpack()
|
||||||
|
{
|
||||||
|
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
||||||
|
|
||||||
|
fi->readx(&fat_head, sizeof(fat_head));
|
||||||
|
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|
||||||
|
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
||||||
|
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||||
|
switch (arch[j].cputype) {
|
||||||
|
default: return false;
|
||||||
|
case PackMachFat::CPU_TYPE_I386: {
|
||||||
|
PackMachI386 packer(fi);
|
||||||
|
if (!packer.canUnpack())
|
||||||
|
return 0;
|
||||||
|
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
|
||||||
|
} break;
|
||||||
|
case PackMachFat::CPU_TYPE_POWERPC: {
|
||||||
|
PackMachPPC32 packer(fi);
|
||||||
|
if (!packer.canUnpack())
|
||||||
|
return 0;
|
||||||
|
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
|
||||||
|
} break;
|
||||||
|
} // switch cputype
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackMachFat::buildLoader(const Filter */*ft*/)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Linker* PackMachFat::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86; // sham
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackMachFat::list()
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et
|
vi:ts=4:et
|
||||||
*/
|
*/
|
||||||
|
|||||||
+449
-114
@@ -29,161 +29,328 @@
|
|||||||
#ifndef __UPX_P_MACHO_H
|
#ifndef __UPX_P_MACHO_H
|
||||||
#define __UPX_P_MACHO_H
|
#define __UPX_P_MACHO_H
|
||||||
|
|
||||||
|
|
||||||
|
struct Mach_fat_header {
|
||||||
|
BE32 magic;
|
||||||
|
enum { // note conflict with java bytecode PackLinuxI386
|
||||||
|
FAT_MAGIC = 0xcafebabe,
|
||||||
|
FAT_MAGIC_SWAB = 0xbebafeca
|
||||||
|
};
|
||||||
|
BE32 nfat_arch; // Number of Mach_fat_arch which follow.
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
struct Mach_fat_arch {
|
||||||
|
BE32 cputype;
|
||||||
|
BE32 cpusubtype;
|
||||||
|
BE32 offset;
|
||||||
|
BE32 size;
|
||||||
|
BE32 align; /* shift count; log base 2 */
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Mach Mach Object executable
|
// Mach Mach Object executable; all structures are target-endian
|
||||||
|
// 'otool' is the Mach analog of 'readelf' (convert executable file to ASCII).
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
struct Mach_header {
|
namespace N_Mach {
|
||||||
BE32 magic;
|
|
||||||
enum {
|
// integral types
|
||||||
MH_MAGIC = 0xfeedface
|
template <class TWord, class TXword, class TAddr, class TOff>
|
||||||
};
|
struct MachITypes
|
||||||
BE32 cputype;
|
{
|
||||||
enum {
|
typedef TWord Word;
|
||||||
CPU_TYPE_POWERPC = 18
|
typedef TXword Xword;
|
||||||
};
|
typedef TAddr Addr;
|
||||||
BE32 cpysubtype;
|
typedef TOff Off;
|
||||||
BE32 filetype;
|
};
|
||||||
enum {
|
|
||||||
MH_EXECUTE = 2
|
template <class TMachITypes>
|
||||||
};
|
struct Mach_header
|
||||||
BE32 ncmds;
|
{
|
||||||
BE32 sizeofcmds;
|
typedef typename TMachITypes::Word Word;
|
||||||
BE32 flags;
|
|
||||||
enum {
|
Word magic;
|
||||||
MH_NOUNDEFS = 1
|
Word cputype;
|
||||||
};
|
Word cpysubtype;
|
||||||
|
Word filetype;
|
||||||
|
Word ncmds;
|
||||||
|
Word sizeofcmds;
|
||||||
|
Word flags;
|
||||||
|
#define WANT_MACH_HEADER_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct Mach_segment_command {
|
template <class TMachITypes>
|
||||||
BE32 cmd;
|
struct Mach_header64
|
||||||
enum {
|
{ // only difference is padding to 0 mod 8
|
||||||
LC_SEGMENT = 0x1,
|
typedef typename TMachITypes::Word Word;
|
||||||
LC_THREAD = 0x4,
|
|
||||||
LC_UNIXTHREAD = 0x5,
|
Word magic;
|
||||||
LC_LOAD_DYLINKER = 0xe
|
Word cputype;
|
||||||
};
|
Word cpysubtype;
|
||||||
BE32 cmdsize;
|
Word filetype;
|
||||||
|
Word ncmds;
|
||||||
|
Word sizeofcmds;
|
||||||
|
Word flags;
|
||||||
|
Word reserved; // pad to 0 mod 8
|
||||||
|
#define WANT_MACH_HEADER_ENUM 1
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
struct Mach_segment_command
|
||||||
|
{
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
|
||||||
|
Word cmd;
|
||||||
|
Word cmdsize;
|
||||||
char segname[16];
|
char segname[16];
|
||||||
BE32 vmaddr;
|
Addr vmaddr;
|
||||||
BE32 vmsize;
|
Addr vmsize;
|
||||||
BE32 fileoff;
|
Off fileoff;
|
||||||
BE32 filesize;
|
Off filesize;
|
||||||
BE32 maxprot;
|
Word maxprot;
|
||||||
enum {
|
Word initprot;
|
||||||
VM_PROT_READ = 1,
|
Word nsects;
|
||||||
VM_PROT_WRITE = 2,
|
Word flags;
|
||||||
VM_PROT_EXECUTE = 4
|
#define WANT_MACH_SEGMENT_ENUM 1
|
||||||
};
|
#include "p_mach_enum.h"
|
||||||
BE32 initprot;
|
|
||||||
BE32 nsects;
|
|
||||||
BE32 flags;
|
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct Mach_section {
|
template <class TMachITypes>
|
||||||
|
struct Mach_section_command
|
||||||
|
{
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Addr Addr;
|
||||||
|
typedef typename TMachITypes::Off Off;
|
||||||
|
|
||||||
char sectname[16];
|
char sectname[16];
|
||||||
char segname[16];
|
char segname[16];
|
||||||
BE32 addr; /* memory address */
|
Addr addr; /* memory address */
|
||||||
BE32 size; /* size in bytes */
|
Addr size; /* size in bytes */
|
||||||
BE32 offset; /* file offset */
|
Word offset; /* file offset */ // FIXME: 64 bit?
|
||||||
BE32 align; /* power of 2 */
|
Word align; /* power of 2 */
|
||||||
BE32 reloff; /* file offset of relocation entries */
|
Word reloff; /* file offset of relocation entries */
|
||||||
BE32 nreloc; /* number of relocation entries */
|
Word nreloc; /* number of relocation entries */
|
||||||
BE32 flags; /* section type and attributes */
|
Word flags; /* section type and attributes */
|
||||||
enum {
|
Word reserved1;
|
||||||
S_REGULAR = 0,
|
Word reserved2;
|
||||||
S_ZEROFILL,
|
#define WANT_MACH_SECTION_ENUM 1
|
||||||
S_CSTRING_LITERALS,
|
#include "p_mach_enum.h"
|
||||||
S_4BYTE_LITERALS,
|
|
||||||
S_8BYTE_LITERALS,
|
|
||||||
S_LITERAL_POINTERS,
|
|
||||||
S_NON_LAZY_SYMBOL_POINTERS,
|
|
||||||
S_LAZY_SYMBOL_POINTERS,
|
|
||||||
S_SYMBOL_STUBS,
|
|
||||||
S_MOD_INIT_FUNC_POINTERS,
|
|
||||||
S_MOD_TERM_FNC_POINTERS,
|
|
||||||
S_COALESCED
|
|
||||||
};
|
|
||||||
enum {
|
|
||||||
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
|
|
||||||
S_ATTR_NO_TOC = 0x40000000,
|
|
||||||
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
|
|
||||||
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
|
|
||||||
S_ATTR_EXT_RELOC = 0x00000200,
|
|
||||||
S_ATTR_LOC_RELOC = 0x00000100
|
|
||||||
};
|
|
||||||
BE32 reserved1;
|
|
||||||
BE32 reserved2;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct Mach_ppc_thread_state {
|
template <class TMachITypes>
|
||||||
BE32 srr0; /* Instruction address register (PC; entry addr) */
|
struct Mach_ppc_thread_state
|
||||||
BE32 srr1; /* Machine state register (supervisor) */
|
{
|
||||||
BE32 r0, r1, r2, r3, r4, r5, r6, r7;
|
typedef typename TMachITypes::Addr Addr;
|
||||||
BE32 r8, r9,r10,r11,r12,r13,r14,r15;
|
|
||||||
BE32 r16,r17,r18,r19,r20,r21,r22,r23;
|
|
||||||
BE32 r24,r25,r26,r27,r28,r29,r30,r31;
|
|
||||||
|
|
||||||
BE32 cr; /* Condition register */
|
Addr srr0; /* Instruction address register (PC; entry addr) */
|
||||||
BE32 xer; /* User's integer exception register */
|
Addr srr1; /* Machine state register (supervisor) */
|
||||||
BE32 lr; /* Link register */
|
Addr r0, r1, r2, r3, r4, r5, r6, r7;
|
||||||
BE32 ctr; /* Count register */
|
Addr r8, r9,r10,r11,r12,r13,r14,r15;
|
||||||
BE32 mq; /* MQ register (601 only) */
|
Addr r16,r17,r18,r19,r20,r21,r22,r23;
|
||||||
|
Addr r24,r25,r26,r27,r28,r29,r30,r31;
|
||||||
|
|
||||||
BE32 vrsave; /* Vector Save Register */
|
Addr cr; /* Condition register */ // FIXME: Word?
|
||||||
|
Addr xer; /* User's integer exception register */
|
||||||
|
Addr lr; /* Link register */
|
||||||
|
Addr ctr; /* Count register */
|
||||||
|
Addr mq; /* MQ register (601 only) */
|
||||||
|
|
||||||
|
Addr vrsave; /* Vector Save Register */
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
struct Mach_thread_command {
|
template <class TMachITypes>
|
||||||
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
struct Mach_i386_thread_state
|
||||||
BE32 cmdsize; /* total size of this command */
|
{
|
||||||
BE32 flavor;
|
typedef typename TMachITypes::Word Word;
|
||||||
enum {
|
|
||||||
PPC_THREAD_STATE = 1
|
Word eax, ebx, ecx, edx;
|
||||||
};
|
Word edi, esi, ebp;
|
||||||
BE32 count; /* sizeof(following_thread_state)/4 */
|
Word esp, ss;
|
||||||
enum {
|
Word eflags;
|
||||||
PPC_THREAD_STATE_COUNT = sizeof(struct Mach_ppc_thread_state)/4
|
Word eip, cs;
|
||||||
};
|
Word ds, es, fs, gs;
|
||||||
struct Mach_ppc_thread_state state;
|
|
||||||
}
|
}
|
||||||
__attribute_packed;
|
__attribute_packed;
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
struct Mach_i386_new_thread_state
|
||||||
|
{
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
|
||||||
|
Word gs, fs, es, ds;
|
||||||
|
Word edi, esi, ebp, esp;
|
||||||
|
Word ebx, edx, ecx, eax;
|
||||||
|
Word eip, cs, efl;
|
||||||
|
Word uesp, ss;
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
} // namespace N_Mach
|
||||||
|
|
||||||
|
namespace N_Mach32 {
|
||||||
|
|
||||||
|
} // namespace N_Mach32
|
||||||
|
|
||||||
|
namespace N_Mach64 {
|
||||||
|
|
||||||
|
template <class TMachITypes>
|
||||||
|
struct Mach_ppc_thread_state64
|
||||||
|
{
|
||||||
|
typedef typename TMachITypes::Word Word;
|
||||||
|
typedef typename TMachITypes::Xword Xword;
|
||||||
|
|
||||||
|
Xword srr0; /* Instruction address register (PC; entry addr) */
|
||||||
|
Xword srr1; /* Machine state register (supervisor) */
|
||||||
|
Xword r0, r1, r2, r3, r4, r5, r6, r7;
|
||||||
|
Xword r8, r9,r10,r11,r12,r13,r14,r15;
|
||||||
|
Xword r16,r17,r18,r19,r20,r21,r22,r23;
|
||||||
|
Xword r24,r25,r26,r27,r28,r29,r30,r31;
|
||||||
|
|
||||||
|
Word cr; /* Condition register */ // FIXME: Xword?
|
||||||
|
Xword xer; /* User's integer exception register */
|
||||||
|
Xword lr; /* Link register */
|
||||||
|
Xword ctr; /* Count register */
|
||||||
|
|
||||||
|
Word vrsave; /* Vector Save Register */
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
} // namespace N_Mach64
|
||||||
|
|
||||||
|
namespace N_Mach {
|
||||||
|
|
||||||
|
template <class TP>
|
||||||
|
struct MachClass_32
|
||||||
|
{
|
||||||
|
typedef TP BeLePolicy;
|
||||||
|
|
||||||
|
// integral types
|
||||||
|
typedef typename TP::U16 U16;
|
||||||
|
typedef typename TP::U32 U32;
|
||||||
|
typedef typename TP::U64 U64;
|
||||||
|
typedef N_Mach::MachITypes<U32, U64, U32, U32> MachITypes;
|
||||||
|
#if (ACC_CC_BORLANDC)
|
||||||
|
typedef U32 Addr;
|
||||||
|
#else
|
||||||
|
typedef typename MachITypes::Addr Addr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mach types
|
||||||
|
typedef N_Mach::Mach_header<MachITypes> Mach_header;
|
||||||
|
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
|
||||||
|
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
|
||||||
|
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
|
||||||
|
typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
BeLePolicy::compileTimeAssertions();
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(Addr) == 4)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class TP>
|
||||||
|
struct MachClass_64
|
||||||
|
{
|
||||||
|
typedef TP BeLePolicy;
|
||||||
|
|
||||||
|
// integral types
|
||||||
|
typedef typename TP::U16 U16;
|
||||||
|
typedef typename TP::U32 U32;
|
||||||
|
typedef typename TP::U64 U64;
|
||||||
|
typedef N_Mach::MachITypes<U32, U64, U64, U64> MachITypes;
|
||||||
|
|
||||||
|
// Mach types
|
||||||
|
typedef N_Mach::Mach_header64<MachITypes> Mach_header;
|
||||||
|
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
|
||||||
|
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
|
||||||
|
|
||||||
|
static void compileTimeAssertions() {
|
||||||
|
BeLePolicy::compileTimeAssertions();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace N_Mach
|
||||||
|
|
||||||
|
typedef N_Mach::MachClass_32<N_BELE_CTP::HostPolicy> MachClass_Host32;
|
||||||
|
typedef N_Mach::MachClass_64<N_BELE_CTP::HostPolicy> MachClass_Host64;
|
||||||
|
typedef N_Mach::MachClass_32<N_BELE_CTP::BEPolicy> MachClass_BE32;
|
||||||
|
typedef N_Mach::MachClass_64<N_BELE_CTP::BEPolicy> MachClass_BE64;
|
||||||
|
typedef N_Mach::MachClass_32<N_BELE_CTP::LEPolicy> MachClass_LE32;
|
||||||
|
typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> MachClass_LE64;
|
||||||
|
|
||||||
|
// shortcuts
|
||||||
|
typedef MachClass_Host32::Mach_segment_command Mach32_segment_command;
|
||||||
|
typedef MachClass_Host32::Mach_section_command Mach32_section_command;
|
||||||
|
|
||||||
|
typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
|
||||||
|
typedef MachClass_Host64::Mach_section_command Mach64_section_command;
|
||||||
|
|
||||||
|
typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
|
||||||
|
typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
|
||||||
|
|
||||||
|
typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
|
||||||
|
typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
|
||||||
|
|
||||||
|
typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
|
||||||
|
typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
|
||||||
|
|
||||||
|
typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
|
||||||
|
typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
|
||||||
|
|
||||||
|
typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
|
||||||
|
typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
|
||||||
#include "p_unix.h"
|
#include "p_unix.h"
|
||||||
|
|
||||||
|
|
||||||
class PackMachPPC32 : public PackUnixBe32
|
template <class TMachClass>
|
||||||
|
class PackMachBase : public PackUnix
|
||||||
{
|
{
|
||||||
typedef PackUnixBe32 super;
|
typedef PackUnix super;
|
||||||
|
protected:
|
||||||
|
typedef TMachClass MachClass;
|
||||||
|
typedef typename MachClass::BeLePolicy BeLePolicy;
|
||||||
|
typedef typename MachClass::MachITypes MachITypes;
|
||||||
|
// integral types
|
||||||
|
typedef typename MachClass::U16 U16;
|
||||||
|
typedef typename MachClass::U32 U32;
|
||||||
|
typedef typename MachClass::U64 U64;
|
||||||
|
typedef typename MachClass::Addr Addr;
|
||||||
|
// Mach types
|
||||||
|
typedef typename MachClass::Mach_header Mach_header;
|
||||||
|
typedef typename MachClass::Mach_segment_command Mach_segment_command;
|
||||||
|
typedef typename MachClass::Mach_section_command Mach_section_command;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackMachPPC32(InputFile *f);
|
PackMachBase(InputFile *, unsigned cpuid, unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
|
||||||
virtual ~PackMachPPC32();
|
virtual ~PackMachBase();
|
||||||
virtual int getVersion() const { return 13; }
|
virtual int getVersion() const { return 13; }
|
||||||
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
|
|
||||||
virtual const char *getName() const { return "Mach/ppc32"; }
|
|
||||||
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; }
|
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
|
||||||
|
|
||||||
// called by the generic pack()
|
// called by the generic pack()
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo) = 0;
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void buildLoader(const Filter *ft);
|
|
||||||
virtual Linker* newLinker() const;
|
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
virtual void patchLoaderChecksum();
|
virtual void patchLoaderChecksum();
|
||||||
virtual void updateLoader(OutputFile *);
|
virtual void updateLoader(OutputFile *);
|
||||||
@@ -196,6 +363,13 @@ protected:
|
|||||||
virtual void defineSymbols(Filter const *);
|
virtual void defineSymbols(Filter const *);
|
||||||
virtual void addStubEntrySections(Filter const *);
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
|
static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb);
|
||||||
|
|
||||||
|
unsigned my_cputype;
|
||||||
|
unsigned my_thread_flavor;
|
||||||
|
unsigned my_thread_state_word_count;
|
||||||
|
unsigned my_thread_command_size;
|
||||||
|
|
||||||
unsigned n_segment;
|
unsigned n_segment;
|
||||||
unsigned sz_segment;
|
unsigned sz_segment;
|
||||||
unsigned sz_mach_headers;
|
unsigned sz_mach_headers;
|
||||||
@@ -205,11 +379,172 @@ protected:
|
|||||||
|
|
||||||
Mach_header mhdro;
|
Mach_header mhdro;
|
||||||
Mach_segment_command segcmdo;
|
Mach_segment_command segcmdo;
|
||||||
Mach_thread_command threado;
|
|
||||||
|
struct b_info { // 12-byte header before each compressed block
|
||||||
|
U32 sz_unc; // uncompressed_size
|
||||||
|
U32 sz_cpr; // compressed_size
|
||||||
|
unsigned char b_method; // compression algorithm
|
||||||
|
unsigned char b_ftid; // filter id
|
||||||
|
unsigned char b_cto8; // filter parameter
|
||||||
|
unsigned char b_unused;
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
struct l_info { // 12-byte trailer in header for loader
|
||||||
|
U32 l_checksum;
|
||||||
|
LE32 l_magic;
|
||||||
|
U16 l_lsize;
|
||||||
|
unsigned char l_version;
|
||||||
|
unsigned char l_format;
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
|
struct p_info { // 12-byte packed program header
|
||||||
|
U32 p_progid;
|
||||||
|
U32 p_filesize;
|
||||||
|
U32 p_blocksize;
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
|
||||||
struct l_info linfo;
|
struct l_info linfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PackMachPPC32 : public PackMachBase<MachClass_BE32>
|
||||||
|
{
|
||||||
|
typedef PackMachBase<MachClass_BE32> super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC,
|
||||||
|
Mach_thread_command::PPC_THREAD_STATE,
|
||||||
|
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado)) { }
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_PPC32; }
|
||||||
|
virtual const char *getName() const { return "Mach/ppc32"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; }
|
||||||
|
|
||||||
|
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
||||||
|
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
||||||
|
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
|
||||||
|
virtual void set_native64(void *b, acc_uint64l_t v) const { set_be64(b, v); }
|
||||||
|
virtual void set_native32(void *b, unsigned v) const { set_be32(b, v); }
|
||||||
|
virtual void set_native16(void *b, unsigned v) const { set_be16(b, v); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo);
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
|
||||||
|
struct Mach_thread_command
|
||||||
|
{
|
||||||
|
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||||
|
BE32 cmdsize; /* total size of this command */
|
||||||
|
BE32 flavor;
|
||||||
|
BE32 count; /* sizeof(following_thread_state)/4 */
|
||||||
|
Mach_ppc_thread_state state;
|
||||||
|
#define WANT_MACH_THREAD_ENUM
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
Mach_thread_command threado;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackMachI386 : public PackMachBase<MachClass_LE32>
|
||||||
|
{
|
||||||
|
typedef PackMachBase<MachClass_LE32> super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386,
|
||||||
|
(unsigned)Mach_thread_command::i386_THREAD_STATE,
|
||||||
|
sizeof(Mach_i386_thread_state)>>2, sizeof(threado)) { }
|
||||||
|
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_i386; }
|
||||||
|
virtual const char *getName() const { return "Mach/i386"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "i386-darwin.macho"; }
|
||||||
|
protected:
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||||
|
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||||
|
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
||||||
|
virtual void set_native64(void *b, acc_uint64l_t v) const { set_le64(b, v); }
|
||||||
|
virtual void set_native32(void *b, unsigned v) const { set_le32(b, v); }
|
||||||
|
virtual void set_native16(void *b, unsigned v) const { set_le16(b, v); }
|
||||||
|
|
||||||
|
virtual void pack1_setup_threado(OutputFile *const fo);
|
||||||
|
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
|
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual void addStubEntrySections(Filter const *);
|
||||||
|
|
||||||
|
struct Mach_thread_command
|
||||||
|
{
|
||||||
|
LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||||
|
LE32 cmdsize; /* total size of this command */
|
||||||
|
LE32 flavor;
|
||||||
|
LE32 count; /* sizeof(following_thread_state)/4 */
|
||||||
|
Mach_i386_thread_state state;
|
||||||
|
#define WANT_MACH_THREAD_ENUM
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
Mach_thread_command threado;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PackMachFat : public Packer
|
||||||
|
{
|
||||||
|
typedef Packer super;
|
||||||
|
public:
|
||||||
|
PackMachFat(InputFile *f);
|
||||||
|
virtual ~PackMachFat();
|
||||||
|
|
||||||
|
virtual int getVersion() const { return 13; }
|
||||||
|
virtual int getFormat() const { return UPX_F_MACH_FAT; }
|
||||||
|
virtual const char *getName() const { return "Mach/fat"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "fat-darwin.macho"; }
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// implementation
|
||||||
|
virtual void pack(OutputFile *fo);
|
||||||
|
virtual void unpack(OutputFile *fo);
|
||||||
|
virtual void list();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool canPack();
|
||||||
|
virtual int canUnpack();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// loader core
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
|
#if (ACC_CC_BORLANDC)
|
||||||
|
public:
|
||||||
|
#endif
|
||||||
|
enum { N_FAT_ARCH = 5 };
|
||||||
|
protected:
|
||||||
|
struct Fat_head {
|
||||||
|
struct Mach_fat_header fat;
|
||||||
|
struct Mach_fat_arch arch[N_FAT_ARCH];
|
||||||
|
}
|
||||||
|
__attribute_packed;
|
||||||
|
Fat_head fat_head;
|
||||||
|
|
||||||
|
// UI handler
|
||||||
|
UiPacker *uip;
|
||||||
|
|
||||||
|
// linker
|
||||||
|
Linker *linker;
|
||||||
|
#define WANT_MACH_HEADER_ENUM
|
||||||
|
#include "p_mach_enum.h"
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/* p_mach_enum.h --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 2007 John F. Reiser
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// Use the preprocessor to work around
|
||||||
|
// - that the types embedding these enums have to be PODs, and
|
||||||
|
// deriving from an empty base class (which is the usual C++ way
|
||||||
|
// of "importing" enums) does not yield a POD any more
|
||||||
|
// - that older compilers do not correctly perform EBCO
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifdef WANT_MACH_HEADER_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_HEADER_ENUM
|
||||||
|
enum { // magic
|
||||||
|
MH_MAGIC = 0xfeedface
|
||||||
|
};
|
||||||
|
enum { // cputype
|
||||||
|
CPU_TYPE_I386 = 7,
|
||||||
|
CPU_TYPE_POWERPC = 0x00000012,
|
||||||
|
CPU_TYPE_POWERPC64 = 0x01000012
|
||||||
|
};
|
||||||
|
enum { // filetype
|
||||||
|
MH_EXECUTE = 2
|
||||||
|
};
|
||||||
|
enum { // flags
|
||||||
|
MH_NOUNDEFS = 1
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#ifdef WANT_MACH_SEGMENT_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_SEGMENT_ENUM
|
||||||
|
enum { // cmd
|
||||||
|
LC_SEGMENT = 0x1,
|
||||||
|
LC_THREAD = 0x4,
|
||||||
|
LC_UNIXTHREAD = 0x5,
|
||||||
|
LC_LOAD_DYLINKER = 0xe,
|
||||||
|
LC_SEGMENT_64 = 0x19
|
||||||
|
};
|
||||||
|
enum { // maxprot
|
||||||
|
VM_PROT_READ = 1,
|
||||||
|
VM_PROT_WRITE = 2,
|
||||||
|
VM_PROT_EXECUTE = 4
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#ifdef WANT_MACH_SECTION_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_SECTION_ENUM
|
||||||
|
enum { // section flags
|
||||||
|
S_REGULAR = 0,
|
||||||
|
S_ZEROFILL,
|
||||||
|
S_CSTRING_LITERALS,
|
||||||
|
S_4BYTE_LITERALS,
|
||||||
|
S_8BYTE_LITERALS,
|
||||||
|
S_LITERAL_POINTERS,
|
||||||
|
S_NON_LAZY_SYMBOL_POINTERS,
|
||||||
|
S_LAZY_SYMBOL_POINTERS,
|
||||||
|
S_SYMBOL_STUBS,
|
||||||
|
S_MOD_INIT_FUNC_POINTERS,
|
||||||
|
S_MOD_TERM_FNC_POINTERS,
|
||||||
|
S_COALESCED
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
S_ATTR_PURE_INSTRUCTIONS = 0x80000000,
|
||||||
|
S_ATTR_NO_TOC = 0x40000000,
|
||||||
|
S_ATTR_STRIP_STATIC_SYMS = 0x20000000,
|
||||||
|
S_ATTR_SOME_INSTRUCTIONS = 0x00000400,
|
||||||
|
S_ATTR_EXT_RELOC = 0x00000200,
|
||||||
|
S_ATTR_LOC_RELOC = 0x00000100
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#ifdef WANT_MACH_THREAD_ENUM /*{*/
|
||||||
|
#undef WANT_MACH_THREAD_ENUM
|
||||||
|
enum { // thread flavor
|
||||||
|
PPC_THREAD_STATE = 1,
|
||||||
|
i386_THREAD_STATE = 1,
|
||||||
|
i386_OLD_THREAD_STATE = -1
|
||||||
|
};
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=4:et
|
||||||
|
*/
|
||||||
|
|
||||||
+19
-8
@@ -318,7 +318,8 @@ void PackPs1::buildLoader(const Filter *)
|
|||||||
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp), 4u);
|
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp), 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
foundBss = findBssSection();
|
if (isCon || !isCon && M_IS_LZMA(ph.method))
|
||||||
|
foundBss = findBssSection();
|
||||||
|
|
||||||
if (M_IS_LZMA(ph.method) && !buildPart2)
|
if (M_IS_LZMA(ph.method) && !buildPart2)
|
||||||
{
|
{
|
||||||
@@ -370,16 +371,20 @@ void PackPs1::buildLoader(const Filter *)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (M_IS_LZMA(ph.method))
|
if (M_IS_LZMA(ph.method))
|
||||||
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
|
addLoader(!foundBss ? "cdb.start.lzma" : "bss.cdb.start.lzma", "pad.code",
|
||||||
|
!foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma",
|
||||||
|
method, "cdb.lzma.cpr",
|
||||||
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||||
"lzma.exec", NULL);
|
"lzma.exec", NULL);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
assert(foundBss != true);
|
||||||
addLoader("cdb.start", "pad.code", "cdb.entry",
|
addLoader("cdb.start", "pad.code", "cdb.entry",
|
||||||
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
|
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
|
||||||
method,
|
method,
|
||||||
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||||
!foundBss ? "cdb.exit" : "bss.exit",
|
"cdb.exit", NULL);
|
||||||
"pad.code", NULL);
|
}
|
||||||
}
|
}
|
||||||
addLoader("UPX1HEAD", "IDENTSTR", NULL);
|
addLoader("UPX1HEAD", "IDENTSTR", NULL);
|
||||||
}
|
}
|
||||||
@@ -554,7 +559,9 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? "cdb.entry.lzma" : "cdb.entry");
|
const char* entry_lzma = !foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma";
|
||||||
|
|
||||||
|
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? entry_lzma : "cdb.entry");
|
||||||
e_len = (lsize - d_len) - h_len;
|
e_len = (lsize - d_len) - h_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,7 +585,7 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
|
|
||||||
unsigned pad = 0;
|
unsigned pad = 0;
|
||||||
|
|
||||||
if (!opt->ps1_exe.no_align)
|
if (!opt->ps1_exe.no_align || !isCon)
|
||||||
{
|
{
|
||||||
pad = oh.tx_len;
|
pad = oh.tx_len;
|
||||||
oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC);
|
oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC);
|
||||||
@@ -611,8 +618,12 @@ void PackPs1::pack(OutputFile *fo)
|
|||||||
linker->defineSymbol("PSVR", FIX_PSVR);
|
linker->defineSymbol("PSVR", FIX_PSVR);
|
||||||
linker->defineSymbol("CPDO", comp_data_start);
|
linker->defineSymbol("CPDO", comp_data_start);
|
||||||
if (M_IS_LZMA(ph.method))
|
if (M_IS_LZMA(ph.method))
|
||||||
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
|
{
|
||||||
- getLoaderSectionStart("cdb.entry.lzma"));
|
unsigned entry_lzma = getLoaderSectionStart( !foundBss ? "cdb.entry.lzma" :
|
||||||
|
"bss.cdb.entry.lzma");
|
||||||
|
|
||||||
|
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec") - entry_lzma);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
relocateLoader();
|
relocateLoader();
|
||||||
|
|||||||
+2
-1
@@ -67,11 +67,12 @@ const int *PackTmt::getFilters() const
|
|||||||
|
|
||||||
|
|
||||||
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range,
|
unsigned range,
|
||||||
unsigned upper_limit) const
|
unsigned upper_limit) const
|
||||||
{
|
{
|
||||||
// make sure the decompressor will be paragraph aligned
|
// make sure the decompressor will be paragraph aligned
|
||||||
unsigned o = super::findOverlapOverhead(buf, range, upper_limit);
|
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
||||||
o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf);
|
o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ protected:
|
|||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
|
|
||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
virtual void buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
|||||||
+7
-3
@@ -173,8 +173,10 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft)
|
|||||||
compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy);
|
compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy);
|
||||||
|
|
||||||
if (ph.c_len < ph.u_len) {
|
if (ph.c_len < ph.u_len) {
|
||||||
|
const upx_bytep tbuf = NULL;
|
||||||
|
if (ft.id == 0) tbuf = ibuf;
|
||||||
ph.overlap_overhead = OVERHEAD;
|
ph.overlap_overhead = OVERHEAD;
|
||||||
if (!testOverlappingDecompression(obuf, ph.overlap_overhead)) {
|
if (!testOverlappingDecompression(obuf, tbuf, ph.overlap_overhead)) {
|
||||||
// not in-place compressible
|
// not in-place compressible
|
||||||
ph.c_len = ph.u_len;
|
ph.c_len = ph.u_len;
|
||||||
}
|
}
|
||||||
@@ -353,8 +355,10 @@ void PackUnix::packExtent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ph.c_len < ph.u_len) {
|
if (ph.c_len < ph.u_len) {
|
||||||
|
const upx_bytep tbuf = NULL;
|
||||||
|
if (ft == NULL || ft->id == 0) tbuf = ibuf;
|
||||||
ph.overlap_overhead = OVERHEAD;
|
ph.overlap_overhead = OVERHEAD;
|
||||||
if (!testOverlappingDecompression(obuf, ph.overlap_overhead)) {
|
if (!testOverlappingDecompression(obuf, tbuf, ph.overlap_overhead)) {
|
||||||
// not in-place compressible
|
// not in-place compressible
|
||||||
ph.c_len = ph.u_len;
|
ph.c_len = ph.u_len;
|
||||||
}
|
}
|
||||||
@@ -499,7 +503,7 @@ int PackUnix::canUnpack()
|
|||||||
|
|
||||||
fi->seek(-bufsize, SEEK_END);
|
fi->seek(-bufsize, SEEK_END);
|
||||||
fi->readx(buf, bufsize);
|
fi->readx(buf, bufsize);
|
||||||
if (!getPackHeader(buf, bufsize))
|
if (!getPackHeader(buf, bufsize, true)) // allow incompressible extents
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int l = ph.buf_offset + ph.getPackHeaderSize();
|
int l = ph.buf_offset + ph.getPackHeaderSize();
|
||||||
|
|||||||
+1
-1
@@ -235,7 +235,7 @@ public:
|
|||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const upx_byte *getLoader() const;
|
virtual upx_byte *getLoader() const;
|
||||||
virtual int getLoaderSize() const;
|
virtual int getLoaderSize() const;
|
||||||
|
|
||||||
virtual void patchLoader();
|
virtual void patchLoader();
|
||||||
|
|||||||
+102
-9
@@ -44,6 +44,8 @@ static const
|
|||||||
#include "stub/amd64-linux.kernel.vmlinux.h"
|
#include "stub/amd64-linux.kernel.vmlinux.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/arm-linux.kernel.vmlinux.h"
|
#include "stub/arm-linux.kernel.vmlinux.h"
|
||||||
|
static const
|
||||||
|
#include "stub/armeb-linux.kernel.vmlinux.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -66,9 +68,9 @@ PackVmlinuxBase<T>::PackVmlinuxBase(InputFile *f,
|
|||||||
template <class T>
|
template <class T>
|
||||||
PackVmlinuxBase<T>::~PackVmlinuxBase()
|
PackVmlinuxBase<T>::~PackVmlinuxBase()
|
||||||
{
|
{
|
||||||
delete [] shstrtab;
|
|
||||||
delete [] phdri;
|
delete [] phdri;
|
||||||
delete [] shdri;
|
delete [] shdri;
|
||||||
|
delete [] shstrtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -547,18 +549,29 @@ const int *PackVmlinuxI386::getFilters() const
|
|||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int *PackVmlinuxARM::getCompressionMethods(int method, int level) const
|
const int *PackVmlinuxARMEL::getCompressionMethods(int method, int level) const
|
||||||
|
{
|
||||||
|
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int *PackVmlinuxARMEB::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
return Packer::getDefaultCompressionMethods_8(method, level);
|
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *PackVmlinuxARM::getFilters() const
|
const int *PackVmlinuxARMEL::getFilters() const
|
||||||
{
|
{
|
||||||
static const int f50[] = { 0x50, FT_END };
|
static const int f50[] = { 0x50, FT_END };
|
||||||
return f50;
|
return f50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackVmlinuxARMEB::getFilters() const
|
||||||
|
{
|
||||||
|
static const int f51[] = { 0x51, FT_END };
|
||||||
|
return f51;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Examples as of 2004-07-16 [readelf --segments vmlinux # before fiddling]:
|
// Examples as of 2004-07-16 [readelf --segments vmlinux # before fiddling]:
|
||||||
//
|
//
|
||||||
@@ -646,18 +659,29 @@ void PackVmlinuxAMD64::buildLoader(const Filter *ft)
|
|||||||
"LINUX992,IDENTSTR,UPX1HEAD", NULL);
|
"LINUX992,IDENTSTR,UPX1HEAD", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PackVmlinuxARM::is_valid_e_entry(Addr e_entry)
|
bool PackVmlinuxARMEL::is_valid_e_entry(Addr e_entry)
|
||||||
{
|
{
|
||||||
return 0xc0008000==e_entry;
|
return 0xc0008000==e_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
Linker* PackVmlinuxARM::newLinker() const
|
bool PackVmlinuxARMEB::is_valid_e_entry(Addr e_entry)
|
||||||
|
{
|
||||||
|
return 0xc0008000==e_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
Linker* PackVmlinuxARMEL::newLinker() const
|
||||||
{
|
{
|
||||||
return new ElfLinkerArmLE;
|
return new ElfLinkerArmLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker* PackVmlinuxARMEB::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerArmBE;
|
||||||
|
}
|
||||||
|
|
||||||
void PackVmlinuxARM::buildLoader(const Filter *ft)
|
|
||||||
|
|
||||||
|
void PackVmlinuxARMEL::buildLoader(const Filter *ft)
|
||||||
{
|
{
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(stub_arm_linux_kernel_vmlinux, sizeof(stub_arm_linux_kernel_vmlinux));
|
initLoader(stub_arm_linux_kernel_vmlinux, sizeof(stub_arm_linux_kernel_vmlinux));
|
||||||
@@ -679,6 +703,28 @@ void PackVmlinuxARM::buildLoader(const Filter *ft)
|
|||||||
addLoader("IDENTSTR,UPX1HEAD", NULL);
|
addLoader("IDENTSTR,UPX1HEAD", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackVmlinuxARMEB::buildLoader(const Filter *ft)
|
||||||
|
{
|
||||||
|
// prepare loader
|
||||||
|
initLoader(stub_armeb_linux_kernel_vmlinux, sizeof(stub_armeb_linux_kernel_vmlinux));
|
||||||
|
addLoader("LINUX000", NULL);
|
||||||
|
if (ft->id) {
|
||||||
|
assert(ft->calls > 0);
|
||||||
|
addLoader("LINUX010", NULL);
|
||||||
|
}
|
||||||
|
addLoader("LINUX020", NULL);
|
||||||
|
if (ft->id) {
|
||||||
|
addFilter32(ft->id);
|
||||||
|
}
|
||||||
|
addLoader("LINUX030", NULL);
|
||||||
|
if (ph.method == M_NRV2E_8) addLoader("NRV2E", NULL);
|
||||||
|
else if (ph.method == M_NRV2B_8) addLoader("NRV2B", NULL);
|
||||||
|
else if (ph.method == M_NRV2D_8) addLoader("NRV2D", NULL);
|
||||||
|
else if (M_IS_LZMA(ph.method)) addLoader("LZMA_ELF00,LZMA_DEC10,LZMA_DEC30", NULL);
|
||||||
|
else throwBadLoader();
|
||||||
|
addLoader("IDENTSTR,UPX1HEAD", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/i386-linux.kernel.vmlinux-head.h"
|
#include "stub/i386-linux.kernel.vmlinux-head.h"
|
||||||
@@ -686,6 +732,8 @@ static const
|
|||||||
#include "stub/amd64-linux.kernel.vmlinux-head.h"
|
#include "stub/amd64-linux.kernel.vmlinux-head.h"
|
||||||
static const
|
static const
|
||||||
#include "stub/arm-linux.kernel.vmlinux-head.h"
|
#include "stub/arm-linux.kernel.vmlinux-head.h"
|
||||||
|
static const
|
||||||
|
#include "stub/armeb-linux.kernel.vmlinux-head.h"
|
||||||
|
|
||||||
unsigned PackVmlinuxI386::write_vmlinux_head(
|
unsigned PackVmlinuxI386::write_vmlinux_head(
|
||||||
OutputFile *const fo,
|
OutputFile *const fo,
|
||||||
@@ -719,7 +767,15 @@ printf("UnCompressed length=0x%x\n", ph.u_len);
|
|||||||
return sizeof(stub_amd64_linux_kernel_vmlinux_head);
|
return sizeof(stub_amd64_linux_kernel_vmlinux_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackVmlinuxARM::defineDecompressorSymbols()
|
void PackVmlinuxARMEL::defineDecompressorSymbols()
|
||||||
|
{
|
||||||
|
super::defineDecompressorSymbols();
|
||||||
|
linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len);
|
||||||
|
linker->defineSymbol("UNCOMPRESSED_LENGTH", ph.u_len);
|
||||||
|
linker->defineSymbol("METHOD", ph.method);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackVmlinuxARMEB::defineDecompressorSymbols()
|
||||||
{
|
{
|
||||||
super::defineDecompressorSymbols();
|
super::defineDecompressorSymbols();
|
||||||
linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len);
|
linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len);
|
||||||
@@ -744,7 +800,7 @@ void PackVmlinuxAMD64::defineDecompressorSymbols()
|
|||||||
linker->defineSymbol("PHYSICAL_START", phdri[0].p_paddr);
|
linker->defineSymbol("PHYSICAL_START", phdri[0].p_paddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PackVmlinuxARM::write_vmlinux_head(
|
unsigned PackVmlinuxARMEL::write_vmlinux_head(
|
||||||
OutputFile *const fo,
|
OutputFile *const fo,
|
||||||
Shdr *const stxt
|
Shdr *const stxt
|
||||||
)
|
)
|
||||||
@@ -766,8 +822,30 @@ unsigned PackVmlinuxARM::write_vmlinux_head(
|
|||||||
return sizeof(stub_arm_linux_kernel_vmlinux_head);
|
return sizeof(stub_arm_linux_kernel_vmlinux_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PackVmlinuxARMEB::write_vmlinux_head(
|
||||||
|
OutputFile *const fo,
|
||||||
|
Shdr *const stxt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// First word from vmlinux-head.S
|
||||||
|
fo->write(&stub_armeb_linux_kernel_vmlinux_head[0], 4);
|
||||||
|
|
||||||
bool PackVmlinuxARM::has_valid_vmlinux_head()
|
// Second word
|
||||||
|
U32 tmp_u32;
|
||||||
|
unsigned const t = (0xff000000 &
|
||||||
|
BeLePolicy::get32(&stub_armeb_linux_kernel_vmlinux_head[4]))
|
||||||
|
| (0x00ffffff & (0u - 1 + ((3+ ph.c_len)>>2)));
|
||||||
|
tmp_u32 = t;
|
||||||
|
fo->write(&tmp_u32, 4);
|
||||||
|
|
||||||
|
stxt->sh_addralign = 4;
|
||||||
|
stxt->sh_size += sizeof(stub_armeb_linux_kernel_vmlinux_head);
|
||||||
|
|
||||||
|
return sizeof(stub_armeb_linux_kernel_vmlinux_head);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PackVmlinuxARMEL::has_valid_vmlinux_head()
|
||||||
{
|
{
|
||||||
U32 buf[2];
|
U32 buf[2];
|
||||||
fi->seek(p_text->sh_offset + sizeof(stub_arm_linux_kernel_vmlinux_head) -8, SEEK_SET);
|
fi->seek(p_text->sh_offset + sizeof(stub_arm_linux_kernel_vmlinux_head) -8, SEEK_SET);
|
||||||
@@ -781,6 +859,20 @@ bool PackVmlinuxARM::has_valid_vmlinux_head()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PackVmlinuxARMEB::has_valid_vmlinux_head()
|
||||||
|
{
|
||||||
|
U32 buf[2];
|
||||||
|
fi->seek(p_text->sh_offset + sizeof(stub_armeb_linux_kernel_vmlinux_head) -8, SEEK_SET);
|
||||||
|
fi->readx(buf, sizeof(buf));
|
||||||
|
//unsigned const word0 = buf[0];
|
||||||
|
unsigned const word1 = buf[1];
|
||||||
|
if (0xeb==(word1>>24)
|
||||||
|
&& (0x00ffffff& word1)==(0u - 1 + ((3+ ph.c_len)>>2))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool PackVmlinuxI386::has_valid_vmlinux_head()
|
bool PackVmlinuxI386::has_valid_vmlinux_head()
|
||||||
{
|
{
|
||||||
unsigned char buf[5];
|
unsigned char buf[5];
|
||||||
@@ -1058,6 +1150,7 @@ Linker* PackVmlinuxAMD64::newLinker() const
|
|||||||
|
|
||||||
// instantiate instances
|
// instantiate instances
|
||||||
template class PackVmlinuxBase<ElfClass_LE32>;
|
template class PackVmlinuxBase<ElfClass_LE32>;
|
||||||
|
template class PackVmlinuxBase<ElfClass_BE32>;
|
||||||
template class PackVmlinuxBase<ElfClass_LE64>;
|
template class PackVmlinuxBase<ElfClass_LE64>;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+28
-4
@@ -119,14 +119,14 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PackVmlinuxARM : public PackVmlinuxBase<ElfClass_LE32>
|
class PackVmlinuxARMEL : public PackVmlinuxBase<ElfClass_LE32>
|
||||||
{
|
{
|
||||||
typedef PackVmlinuxBase<ElfClass_LE32> super;
|
typedef PackVmlinuxBase<ElfClass_LE32> super;
|
||||||
public:
|
public:
|
||||||
PackVmlinuxARM(InputFile *f) : super(f, Ehdr::EM_ARM,
|
PackVmlinuxARMEL(InputFile *f) : super(f, Ehdr::EM_ARM,
|
||||||
Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { }
|
Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { }
|
||||||
virtual int getFormat() const { return UPX_F_VMLINUX_ARM; }
|
virtual int getFormat() const { return UPX_F_VMLINUX_ARMEL; }
|
||||||
virtual const char *getName() const { return "vmlinux/ARM"; }
|
virtual const char *getName() const { return "vmlinux/armel"; }
|
||||||
virtual const char *getFullName(const options_t *) const { return "arm-linux.kernel.vmlinux"; }
|
virtual const char *getFullName(const options_t *) const { return "arm-linux.kernel.vmlinux"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const;
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
@@ -143,6 +143,30 @@ protected:
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PackVmlinuxARMEB : public PackVmlinuxBase<ElfClass_BE32>
|
||||||
|
{
|
||||||
|
typedef PackVmlinuxBase<ElfClass_BE32> super;
|
||||||
|
public:
|
||||||
|
PackVmlinuxARMEB(InputFile *f) : super(f, Ehdr::EM_ARM,
|
||||||
|
Ehdr::ELFCLASS32, Ehdr::ELFDATA2MSB, "decompress_kernel") { }
|
||||||
|
virtual int getFormat() const { return UPX_F_VMLINUX_ARMEB; }
|
||||||
|
virtual const char *getName() const { return "vmlinux/armeb"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "armeb-linux.kernel.vmlinux"; }
|
||||||
|
virtual const int *getCompressionMethods(int method, int level) const;
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void buildLoader(const Filter *ft);
|
||||||
|
virtual void defineDecompressorSymbols();
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual bool is_valid_e_entry(Addr);
|
||||||
|
virtual bool has_valid_vmlinux_head();
|
||||||
|
virtual unsigned write_vmlinux_head(
|
||||||
|
OutputFile *const fo,
|
||||||
|
Shdr *const stxt
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class PackVmlinuxAMD64 : public PackVmlinuxBase<ElfClass_LE64>
|
class PackVmlinuxAMD64 : public PackVmlinuxBase<ElfClass_LE64>
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ protected:
|
|||||||
virtual void buildLoader(const Filter *ft);
|
virtual void buildLoader(const Filter *ft);
|
||||||
virtual Linker* newLinker() const;
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
// virtual const upx_byte *getLoader() const;
|
// virtual upx_byte *getLoader() const;
|
||||||
// virtual int getLoaderSize() const;
|
// virtual int getLoaderSize() const;
|
||||||
|
|
||||||
struct boot_sect_t
|
struct boot_sect_t
|
||||||
|
|||||||
+6
-2
@@ -607,7 +607,8 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||||||
(ih.cpu < 0x14c || ih.cpu > 0x150)
|
(ih.cpu < 0x14c || ih.cpu > 0x150)
|
||||||
|| (ih.opthdrsize != 0xe0)
|
|| (ih.opthdrsize != 0xe0)
|
||||||
|| ((ih.flags & EXECUTABLE) == 0)
|
|| ((ih.flags & EXECUTABLE) == 0)
|
||||||
|| (ih.subsystem != 2 && ih.subsystem != 3 && ih.subsystem != 1)
|
|| (ih.subsystem != 2 && ih.subsystem != 3
|
||||||
|
&& ih.subsystem != 1 && ih.subsystem != 9)
|
||||||
|| (ih.entry == 0 && !isdll)
|
|| (ih.entry == 0 && !isdll)
|
||||||
|| (ih.ddirsentries != 16)
|
|| (ih.ddirsentries != 16)
|
||||||
|| IDSIZE(PEDIR_EXCEPTION) // is this used on i386?
|
|| IDSIZE(PEDIR_EXCEPTION) // is this used on i386?
|
||||||
@@ -615,6 +616,9 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||||||
))
|
))
|
||||||
throwCantPack("unexpected value in PE header (try --force)");
|
throwCantPack("unexpected value in PE header (try --force)");
|
||||||
|
|
||||||
|
if (ih.subsystem == 9)
|
||||||
|
throwCantPack("x86/wince files are not yet supported");
|
||||||
|
|
||||||
if (IDSIZE(PEDIR_SEC))
|
if (IDSIZE(PEDIR_SEC))
|
||||||
IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0;
|
IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0;
|
||||||
if (IDSIZE(PEDIR_COMRT))
|
if (IDSIZE(PEDIR_COMRT))
|
||||||
@@ -717,7 +721,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||||||
|
|
||||||
//OutputFile::dump("x1", ibuf, usize);
|
//OutputFile::dump("x1", ibuf, usize);
|
||||||
|
|
||||||
// some checks for broken linkers - disable filter if neccessary
|
// some checks for broken linkers - disable filter if necessary
|
||||||
bool allow_filter = true;
|
bool allow_filter = true;
|
||||||
if (ih.codebase == ih.database
|
if (ih.codebase == ih.database
|
||||||
|| ih.codebase + ih.codesize > ih.imagesize
|
|| ih.codebase + ih.codesize > ih.imagesize
|
||||||
|
|||||||
+29
-26
@@ -46,7 +46,7 @@ Packer::Packer(InputFile *f) :
|
|||||||
last_patch(NULL), last_patch_len(0), last_patch_off(0)
|
last_patch(NULL), last_patch_len(0), last_patch_off(0)
|
||||||
{
|
{
|
||||||
if (fi != NULL)
|
if (fi != NULL)
|
||||||
file_size = fi->st.st_size;
|
file_size = fi->st_size();
|
||||||
uip = new UiPacker(this);
|
uip = new UiPacker(this);
|
||||||
memset(&ph, 0, sizeof(ph));
|
memset(&ph, 0, sizeof(ph));
|
||||||
}
|
}
|
||||||
@@ -386,13 +386,16 @@ void Packer::decompress(const upx_bytep in, upx_bytep out,
|
|||||||
// overlapping decompression
|
// overlapping decompression
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf,
|
bool ph_testOverlappingDecompression(const PackHeader &ph,
|
||||||
|
const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned overlap_overhead)
|
unsigned overlap_overhead)
|
||||||
{
|
{
|
||||||
if (ph.c_len >= ph.u_len)
|
if (ph.c_len >= ph.u_len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert((int)overlap_overhead >= 0);
|
assert((int) overlap_overhead >= 0);
|
||||||
|
assert((int) (ph.u_len + overlap_overhead) >= 0);
|
||||||
|
|
||||||
// Because upx_test_overlap() does not use the asm_fast decompressor
|
// Because upx_test_overlap() does not use the asm_fast decompressor
|
||||||
// we must account for extra 3 bytes that asm_fast does use,
|
// we must account for extra 3 bytes that asm_fast does use,
|
||||||
@@ -406,16 +409,17 @@ bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf,
|
|||||||
|
|
||||||
unsigned src_off = ph.u_len + overlap_overhead - ph.c_len;
|
unsigned src_off = ph.u_len + overlap_overhead - ph.c_len;
|
||||||
unsigned new_len = ph.u_len;
|
unsigned new_len = ph.u_len;
|
||||||
int r = upx_test_overlap(buf - src_off, src_off,
|
int r = upx_test_overlap(buf - src_off, tbuf,
|
||||||
ph.c_len, &new_len, ph.method, &ph.compress_result);
|
src_off, ph.c_len, &new_len,
|
||||||
|
ph.method, &ph.compress_result);
|
||||||
return (r == UPX_E_OK && new_len == ph.u_len);
|
return (r == UPX_E_OK && new_len == ph.u_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Packer::testOverlappingDecompression(const upx_bytep buf,
|
bool Packer::testOverlappingDecompression(const upx_bytep buf, const upx_bytep tbuf,
|
||||||
unsigned overlap_overhead) const
|
unsigned overlap_overhead) const
|
||||||
{
|
{
|
||||||
return ph_testOverlappingDecompression(ph, buf, overlap_overhead);
|
return ph_testOverlappingDecompression(ph, buf, tbuf, overlap_overhead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -474,6 +478,7 @@ void Packer::verifyOverlappingDecompression(upx_bytep o_ptr, unsigned o_size, Fi
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range,
|
unsigned range,
|
||||||
unsigned upper_limit) const
|
unsigned upper_limit) const
|
||||||
{
|
{
|
||||||
@@ -481,7 +486,7 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
|||||||
|
|
||||||
// prepare to deal with very pessimistic values
|
// prepare to deal with very pessimistic values
|
||||||
unsigned low = 1;
|
unsigned low = 1;
|
||||||
unsigned high = UPX_MIN(ph.u_len / 4 + 512, upper_limit);
|
unsigned high = UPX_MIN(ph.u_len + 512, upper_limit);
|
||||||
// but be optimistic for first try (speedup)
|
// but be optimistic for first try (speedup)
|
||||||
unsigned m = UPX_MIN(16u, high);
|
unsigned m = UPX_MIN(16u, high);
|
||||||
//
|
//
|
||||||
@@ -493,21 +498,23 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
|||||||
assert(m >= low); assert(m <= high);
|
assert(m >= low); assert(m <= high);
|
||||||
assert(m < overhead || overhead == 0);
|
assert(m < overhead || overhead == 0);
|
||||||
nr++;
|
nr++;
|
||||||
bool success = testOverlappingDecompression(buf, m);
|
bool success = testOverlappingDecompression(buf, tbuf, m);
|
||||||
//printf("testOverlapOverhead: %d %d -> %d\n", nr, m, (int)success);
|
//printf("testOverlapOverhead(%d): %d %d: %d -> %d\n", nr, low, high, m, (int)success);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
overhead = m;
|
overhead = m;
|
||||||
// Succeed early if m lies in [low .. low+range-1], i.e. if
|
// Succeed early if m lies in [low .. low+range-1], i.e. if
|
||||||
// if the range of the current interval is <= range.
|
// if the range of the current interval is <= range.
|
||||||
//if (m <= low + range - 1)
|
// if (m <= low + range - 1)
|
||||||
if (m + 1 <= low + range) // avoid underflow
|
// if (m < low + range)
|
||||||
|
if (m - low < range) // avoid underflow
|
||||||
break;
|
break;
|
||||||
high = m - 1;
|
high = m - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
low = m + 1;
|
low = m + 1;
|
||||||
m = (low + high) / 2;
|
////m = (low + high) / 2;
|
||||||
|
m = (low & high) + ((low ^ high) >> 1); // avoid overflow
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("findOverlapOverhead: %d (%d tries)\n", overhead, nr);
|
//printf("findOverlapOverhead: %d (%d tries)\n", overhead, nr);
|
||||||
@@ -684,7 +691,7 @@ int Packer::patchPackHeader(void *b, int blen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Packer::getPackHeader(void *b, int blen)
|
bool Packer::getPackHeader(void *b, int blen, bool allow_incompressible)
|
||||||
{
|
{
|
||||||
if (!ph.fillPackHeader((unsigned char *)b, blen))
|
if (!ph.fillPackHeader((unsigned char *)b, blen))
|
||||||
return false;
|
return false;
|
||||||
@@ -697,7 +704,9 @@ bool Packer::getPackHeader(void *b, int blen)
|
|||||||
if (!testUnpackVersion(ph.version))
|
if (!testUnpackVersion(ph.version))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ph.c_len >= ph.u_len || (off_t)ph.c_len >= file_size
|
if (ph.c_len > ph.u_len
|
||||||
|
|| (ph.c_len == ph.u_len && !allow_incompressible)
|
||||||
|
|| (off_t)ph.c_len >= file_size
|
||||||
|| ph.version <= 0 || ph.version >= 0xff)
|
|| ph.version <= 0 || ph.version >= 0xff)
|
||||||
throwCantUnpack("header corrupted");
|
throwCantUnpack("header corrupted");
|
||||||
else if ((off_t)ph.u_len > ph.u_file_size)
|
else if ((off_t)ph.u_len > ph.u_file_size)
|
||||||
@@ -722,14 +731,14 @@ bool Packer::getPackHeader(void *b, int blen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Packer::readPackHeader(int len)
|
bool Packer::readPackHeader(int len, bool allow_incompressible)
|
||||||
{
|
{
|
||||||
assert((int)len > 0);
|
assert((int)len > 0);
|
||||||
MemBuffer buf(len);
|
MemBuffer buf(len);
|
||||||
len = fi->read(buf, len);
|
len = fi->read(buf, len);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return false;
|
return false;
|
||||||
return getPackHeader(buf, len);
|
return getPackHeader(buf, len, allow_incompressible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1082,14 +1091,8 @@ void Packer::addLoader(C a, C b, C c, C d, C e, C f, C g, C h, C i, C j)
|
|||||||
void __acc_cdecl_va Packer::addLoaderVA(const char *s, ...)
|
void __acc_cdecl_va Packer::addLoaderVA(const char *s, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
const char *t = s;
|
|
||||||
|
|
||||||
va_start(ap, s);
|
va_start(ap, s);
|
||||||
while (t != NULL)
|
linker->addLoader(s, ap);
|
||||||
{
|
|
||||||
linker->addLoader(t);
|
|
||||||
t = va_arg(ap, const char *);
|
|
||||||
}
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1196,7 +1199,7 @@ void Packer::relocateLoader()
|
|||||||
// The workaround is for hdr_buf and hdr_u_len to describe the Elf headers
|
// The workaround is for hdr_buf and hdr_u_len to describe the Elf headers
|
||||||
// (typically less than 512 bytes) when .text is passed in, and include
|
// (typically less than 512 bytes) when .text is passed in, and include
|
||||||
// them in the calculation of shortest output. Then the result
|
// them in the calculation of shortest output. Then the result
|
||||||
// this->ph.method will say which [single] method to use for everthing.
|
// this->ph.method will say which [single] method to use for everything.
|
||||||
// The Elf headers are never filtered. They are short enough (< 512 bytes)
|
// The Elf headers are never filtered. They are short enough (< 512 bytes)
|
||||||
// that compressing them more than once per method (once here when choosing,
|
// that compressing them more than once per method (once here when choosing,
|
||||||
// once again just before writing [because compressWithFilters discards])
|
// once again just before writing [because compressWithFilters discards])
|
||||||
@@ -1415,7 +1418,7 @@ void Packer::compressWithFilters(upx_bytep i_ptr, unsigned i_len,
|
|||||||
if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len)
|
if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len)
|
||||||
{
|
{
|
||||||
// get results
|
// get results
|
||||||
ph.overlap_overhead = findOverlapOverhead(o_tmp, overlap_range);
|
ph.overlap_overhead = findOverlapOverhead(o_tmp, i_ptr, overlap_range);
|
||||||
buildLoader(&ft);
|
buildLoader(&ft);
|
||||||
lsize = getLoaderSize();
|
lsize = getLoaderSize();
|
||||||
assert(lsize > 0);
|
assert(lsize > 0);
|
||||||
|
|||||||
+4
-2
@@ -203,9 +203,11 @@ protected:
|
|||||||
// util for verifying overlapping decompresion
|
// util for verifying overlapping decompresion
|
||||||
// non-destructive test
|
// non-destructive test
|
||||||
virtual bool testOverlappingDecompression(const upx_bytep buf,
|
virtual bool testOverlappingDecompression(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned overlap_overhead) const;
|
unsigned overlap_overhead) const;
|
||||||
// non-destructive find
|
// non-destructive find
|
||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const;
|
unsigned upper_limit = ~0u) const;
|
||||||
// destructive decompress + verify
|
// destructive decompress + verify
|
||||||
@@ -214,8 +216,8 @@ protected:
|
|||||||
|
|
||||||
// packheader handling
|
// packheader handling
|
||||||
virtual int patchPackHeader(void *b, int blen);
|
virtual int patchPackHeader(void *b, int blen);
|
||||||
virtual bool getPackHeader(void *b, int blen);
|
virtual bool getPackHeader(void *b, int blen, bool allow_incompressible=false);
|
||||||
virtual bool readPackHeader(int len);
|
virtual bool readPackHeader(int len, bool allow_incompressible=false);
|
||||||
virtual void checkAlreadyPacked(const void *b, int blen);
|
virtual void checkAlreadyPacked(const void *b, int blen);
|
||||||
|
|
||||||
// loader core
|
// loader core
|
||||||
|
|||||||
+21
-6
@@ -208,11 +208,14 @@ const char *Packer::getDecompressorSections() const
|
|||||||
if (UPX_F_LINUX_ELF_i386 ==ph.format
|
if (UPX_F_LINUX_ELF_i386 ==ph.format
|
||||||
|| UPX_F_LINUX_ELFI_i386 ==ph.format
|
|| UPX_F_LINUX_ELFI_i386 ==ph.format
|
||||||
|| UPX_F_LINUX_ELF64_AMD ==ph.format
|
|| UPX_F_LINUX_ELF64_AMD ==ph.format
|
||||||
|| UPX_F_LINUX_ELF32_ARMLE==ph.format
|
|| UPX_F_LINUX_ELF32_ARMEL==ph.format
|
||||||
|| UPX_F_LINUX_ELFPPC32 ==ph.format
|
|| UPX_F_LINUX_ELFPPC32 ==ph.format
|
||||||
|| UPX_F_LINUX_ELF32_ARMBE==ph.format
|
|| UPX_F_LINUX_ELF32_ARMEB==ph.format
|
||||||
|| UPX_F_BSD_ELF_i386 ==ph.format
|
|| UPX_F_BSD_ELF_i386 ==ph.format
|
||||||
|| UPX_F_VMLINUX_ARM ==ph.format
|
|| UPX_F_VMLINUX_ARMEL ==ph.format
|
||||||
|
|| UPX_F_VMLINUX_ARMEB ==ph.format
|
||||||
|
|| UPX_F_MACH_PPC32 ==ph.format
|
||||||
|
|| UPX_F_MACH_i386 ==ph.format
|
||||||
) {
|
) {
|
||||||
return opt->small ? lzma_elf_small : lzma_elf_fast;
|
return opt->small ? lzma_elf_small : lzma_elf_fast;
|
||||||
}
|
}
|
||||||
@@ -242,11 +245,14 @@ void Packer::defineDecompressorSymbols()
|
|||||||
if (UPX_F_LINUX_ELF_i386 ==ph.format
|
if (UPX_F_LINUX_ELF_i386 ==ph.format
|
||||||
|| UPX_F_LINUX_ELFI_i386 ==ph.format
|
|| UPX_F_LINUX_ELFI_i386 ==ph.format
|
||||||
|| UPX_F_LINUX_ELF64_AMD ==ph.format
|
|| UPX_F_LINUX_ELF64_AMD ==ph.format
|
||||||
|| UPX_F_LINUX_ELF32_ARMLE==ph.format
|
|| UPX_F_LINUX_ELF32_ARMEL==ph.format
|
||||||
|| UPX_F_LINUX_ELFPPC32 ==ph.format
|
|| UPX_F_LINUX_ELFPPC32 ==ph.format
|
||||||
|| UPX_F_LINUX_ELF32_ARMBE==ph.format
|
|| UPX_F_LINUX_ELF32_ARMEB==ph.format
|
||||||
|| UPX_F_BSD_ELF_i386 ==ph.format
|
|| UPX_F_BSD_ELF_i386 ==ph.format
|
||||||
|| UPX_F_VMLINUX_ARM ==ph.format
|
|| UPX_F_VMLINUX_ARMEL ==ph.format
|
||||||
|
|| UPX_F_VMLINUX_ARMEB ==ph.format
|
||||||
|
|| UPX_F_MACH_PPC32 ==ph.format
|
||||||
|
|| UPX_F_MACH_i386 ==ph.format
|
||||||
) {
|
) {
|
||||||
// ELF calls the decompressor many times; the parameters change!
|
// ELF calls the decompressor many times; the parameters change!
|
||||||
return;
|
return;
|
||||||
@@ -268,6 +274,15 @@ void Packer::defineDecompressorSymbols()
|
|||||||
linker->defineSymbol("lzma_u_len", ph.u_len);
|
linker->defineSymbol("lzma_u_len", ph.u_len);
|
||||||
unsigned stack = getDecompressorWrkmemSize();
|
unsigned stack = getDecompressorWrkmemSize();
|
||||||
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
||||||
|
|
||||||
|
if (ph.format == UPX_F_DOS_EXE)
|
||||||
|
{
|
||||||
|
linker->defineSymbol("lzma_properties_hi", properties / 65536);
|
||||||
|
// -2 for properties
|
||||||
|
linker->defineSymbol("lzma_c_len_hi", (ph.c_len - 2) / 65536);
|
||||||
|
linker->defineSymbol("lzma_u_len_hi", ph.u_len / 65536);
|
||||||
|
linker->defineSymbol("lzma_u_len_segment", (ph.u_len & 0xf0000) >> 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -192,7 +192,9 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
|
|||||||
//
|
//
|
||||||
// linux kernel
|
// linux kernel
|
||||||
//
|
//
|
||||||
if ((p = func(new PackVmlinuxARM(f), user)) != NULL)
|
if ((p = func(new PackVmlinuxARMEL(f), user)) != NULL)
|
||||||
|
return p;
|
||||||
|
if ((p = func(new PackVmlinuxARMEB(f), user)) != NULL)
|
||||||
return p;
|
return p;
|
||||||
if ((p = func(new PackVmlinuxAMD64(f), user)) != NULL)
|
if ((p = func(new PackVmlinuxAMD64(f), user)) != NULL)
|
||||||
return p;
|
return p;
|
||||||
@@ -244,7 +246,9 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
|
|||||||
}
|
}
|
||||||
if ((p = func(new PackBSDI386(f), user)) != NULL)
|
if ((p = func(new PackBSDI386(f), user)) != NULL)
|
||||||
return p;
|
return p;
|
||||||
if ((p = func(new PackLinuxI386(f), user)) != NULL)
|
if ((p = func(new PackMachFat(f), user)) != NULL) // cafebabe conflict
|
||||||
|
return p;
|
||||||
|
if ((p = func(new PackLinuxI386(f), user)) != NULL) // cafebabe conflict
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -264,6 +268,8 @@ Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio
|
|||||||
// Mach (MacOS X PowerPC)
|
// Mach (MacOS X PowerPC)
|
||||||
if ((p = func(new PackMachPPC32(f), user)) != NULL)
|
if ((p = func(new PackMachPPC32(f), user)) != NULL)
|
||||||
return p;
|
return p;
|
||||||
|
if ((p = func(new PackMachI386(f), user)) != NULL)
|
||||||
|
return p;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-32
@@ -50,18 +50,6 @@
|
|||||||
# define strcpy(a,b) strcpy((char *)(a),(const char *)(b))
|
# define strcpy(a,b) strcpy((char *)(a),(const char *)(b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Unicode string compare
|
|
||||||
static bool ustrsame(const void *s1, const void *s2)
|
|
||||||
{
|
|
||||||
unsigned len1 = get_le16(s1);
|
|
||||||
unsigned len2 = get_le16(s2);
|
|
||||||
if (len1 != len2)
|
|
||||||
return false;
|
|
||||||
return memcmp(s1, s2, 2 + 2*len1) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if (__ACC_CXX_HAVE_PLACEMENT_DELETE) || defined(__DJGPP__)
|
#if (__ACC_CXX_HAVE_PLACEMENT_DELETE) || defined(__DJGPP__)
|
||||||
#include "bptr.h"
|
#include "bptr.h"
|
||||||
#define IPTR(type, var) BoundedPtr<type> var(ibuf, ibuf.getSize())
|
#define IPTR(type, var) BoundedPtr<type> var(ibuf, ibuf.getSize())
|
||||||
@@ -1245,6 +1233,12 @@ upx_byte *PeFile::Resource::build()
|
|||||||
newstart = new upx_byte [dirsize()];
|
newstart = new upx_byte [dirsize()];
|
||||||
unsigned bpos = 0,spos = dsize;
|
unsigned bpos = 0,spos = dsize;
|
||||||
build(root,bpos,spos,0);
|
build(root,bpos,spos,0);
|
||||||
|
|
||||||
|
// dirsize() is 4 bytes aligned, so we may need to zero
|
||||||
|
// up to 2 bytes to make valgrind happy
|
||||||
|
while (spos < dirsize())
|
||||||
|
newstart[spos++] = 0;
|
||||||
|
|
||||||
return newstart;
|
return newstart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1349,7 +1343,7 @@ static bool match(unsigned itype, const unsigned char *ntype,
|
|||||||
if (unistr[2 + ic * 2] != (unsigned char) mkeep[ic])
|
if (unistr[2 + ic * 2] != (unsigned char) mkeep[ic])
|
||||||
return false;
|
return false;
|
||||||
return mkeep[ic] == 0 || mkeep[ic] == ',' || mkeep[ic] == '/';
|
return mkeep[ic] == 0 || mkeep[ic] == ',' || mkeep[ic] == '/';
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME this comparison is not too exact
|
// FIXME this comparison is not too exact
|
||||||
@@ -1404,15 +1398,31 @@ void PeFile::processResources(Resource *res)
|
|||||||
oresources = new upx_byte[soresources];
|
oresources = new upx_byte[soresources];
|
||||||
upx_byte *ores = oresources + res->dirsize();
|
upx_byte *ores = oresources + res->dirsize();
|
||||||
|
|
||||||
|
char *keep_icons = NULL; // icon ids in the first icon group
|
||||||
unsigned iconsin1stdir = 0;
|
unsigned iconsin1stdir = 0;
|
||||||
if (opt->win32_pe.compress_icons == 2)
|
if (opt->win32_pe.compress_icons == 2)
|
||||||
while (res->next()) // there is no rewind() in Resource
|
while (res->next()) // there is no rewind() in Resource
|
||||||
if (res->itype() == RT_GROUP_ICON && iconsin1stdir == 0)
|
if (res->itype() == RT_GROUP_ICON && iconsin1stdir == 0)
|
||||||
|
{
|
||||||
iconsin1stdir = get_le16(ibuf + res->offs() + 4);
|
iconsin1stdir = get_le16(ibuf + res->offs() + 4);
|
||||||
|
keep_icons = new char[1 + iconsin1stdir * 9];
|
||||||
|
*keep_icons = 0;
|
||||||
|
for (unsigned ic = 0; ic < iconsin1stdir; ic++)
|
||||||
|
snprintf(keep_icons + strlen(keep_icons), 9, "3/%u,",
|
||||||
|
get_le16(ibuf + res->offs() + 6 + ic * 14 + 12));
|
||||||
|
if (*keep_icons)
|
||||||
|
keep_icons[strlen(keep_icons) - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool compress_icon = opt->win32_pe.compress_icons == 3;
|
// the icon id which should not be compressed when compress_icons == 1
|
||||||
bool compress_idir = false;
|
unsigned first_icon_id = (unsigned) -1;
|
||||||
unsigned iconcnt = 0;
|
if (opt->win32_pe.compress_icons == 1)
|
||||||
|
while (res->next())
|
||||||
|
if (res->itype() == RT_GROUP_ICON && first_icon_id == (unsigned) -1)
|
||||||
|
first_icon_id = get_le16(ibuf + res->offs() + 6 + 12);
|
||||||
|
|
||||||
|
bool compress_icon = opt->win32_pe.compress_icons > 1;
|
||||||
|
bool compress_idir = opt->win32_pe.compress_icons == 3;
|
||||||
|
|
||||||
// some statistics
|
// some statistics
|
||||||
unsigned usize = 0;
|
unsigned usize = 0;
|
||||||
@@ -1426,26 +1436,27 @@ void PeFile::processResources(Resource *res)
|
|||||||
bool do_compress = true;
|
bool do_compress = true;
|
||||||
if (!opt->win32_pe.compress_resources)
|
if (!opt->win32_pe.compress_resources)
|
||||||
do_compress = false;
|
do_compress = false;
|
||||||
else if (rtype == RT_VERSION) // version info
|
|
||||||
do_compress = false;
|
|
||||||
else if (rtype == RT_ICON) // icon
|
else if (rtype == RT_ICON) // icon
|
||||||
do_compress = compress_icon && opt->win32_pe.compress_icons;
|
{
|
||||||
|
if (opt->win32_pe.compress_icons == 0)
|
||||||
|
do_compress = false;
|
||||||
|
else if (opt->win32_pe.compress_icons == 1)
|
||||||
|
if ((first_icon_id == (unsigned) -1
|
||||||
|
|| first_icon_id == res->iname()))
|
||||||
|
do_compress = compress_icon;
|
||||||
|
}
|
||||||
else if (rtype == RT_GROUP_ICON) // icon directory
|
else if (rtype == RT_GROUP_ICON) // icon directory
|
||||||
do_compress = compress_idir && opt->win32_pe.compress_icons;
|
do_compress = compress_idir && opt->win32_pe.compress_icons;
|
||||||
else if (rtype > 0 && rtype < RT_LAST)
|
else if (rtype > 0 && rtype < RT_LAST)
|
||||||
do_compress = opt->win32_pe.compress_rt[rtype] ? true : false;
|
do_compress = opt->win32_pe.compress_rt[rtype] ? true : false;
|
||||||
else if (res->ntype()) // named resource type
|
|
||||||
{
|
|
||||||
const upx_byte * const t = res->ntype();
|
|
||||||
if (ustrsame(t, "\x7\x0T\x0Y\x0P\x0""E\x0L\x0I\x0""B\x0"))
|
|
||||||
do_compress = false; // u"TYPELIB"
|
|
||||||
else if (ustrsame(t, "\x8\x0R\x0""E\x0G\x0I\x0S\x0T\x0R\x0Y\x0"))
|
|
||||||
do_compress = false; // u"REGISTRY"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_compress && opt->win32_pe.keep_resource[0])
|
if (keep_icons)
|
||||||
do_compress ^= match(res->itype(), res->ntype(), res->iname(),
|
do_compress &= !match(res->itype(), res->ntype(), res->iname(),
|
||||||
res->nname(), opt->win32_pe.keep_resource);
|
res->nname(), keep_icons);
|
||||||
|
do_compress &= !match(res->itype(), res->ntype(), res->iname(),
|
||||||
|
res->nname(), "TYPELIB,REGISTRY,16");
|
||||||
|
do_compress &= !match(res->itype(), res->ntype(), res->iname(),
|
||||||
|
res->nname(), opt->win32_pe.keep_resource);
|
||||||
|
|
||||||
if (do_compress)
|
if (do_compress)
|
||||||
{
|
{
|
||||||
@@ -1463,8 +1474,8 @@ void PeFile::processResources(Resource *res)
|
|||||||
memcpy(ores, ibuf + res->offs(), res->size());
|
memcpy(ores, ibuf + res->offs(), res->size());
|
||||||
ibuf.fill(res->offs(), res->size(), FILLVAL);
|
ibuf.fill(res->offs(), res->size(), FILLVAL);
|
||||||
res->newoffs() = ptr_diff(ores,oresources);
|
res->newoffs() = ptr_diff(ores,oresources);
|
||||||
if (rtype == RT_ICON)
|
if (rtype == RT_ICON && opt->win32_pe.compress_icons == 1)
|
||||||
compress_icon = (++iconcnt >= iconsin1stdir || opt->win32_pe.compress_icons == 1);
|
compress_icon = true;
|
||||||
else if (rtype == RT_GROUP_ICON)
|
else if (rtype == RT_GROUP_ICON)
|
||||||
{
|
{
|
||||||
if (opt->win32_pe.compress_icons == 1)
|
if (opt->win32_pe.compress_icons == 1)
|
||||||
@@ -1479,6 +1490,7 @@ void PeFile::processResources(Resource *res)
|
|||||||
}
|
}
|
||||||
soresources = ptr_diff(ores,oresources);
|
soresources = ptr_diff(ores,oresources);
|
||||||
|
|
||||||
|
delete[] keep_icons;
|
||||||
if (!res->clear())
|
if (!res->clear())
|
||||||
{
|
{
|
||||||
// The area occupied by the resource directory is not continuous
|
// The area occupied by the resource directory is not continuous
|
||||||
|
|||||||
+89
-22
@@ -18,10 +18,19 @@ empty :=
|
|||||||
space := $(empty) $(empty)
|
space := $(empty) $(empty)
|
||||||
tab := $(empty) $(empty)
|
tab := $(empty) $(empty)
|
||||||
|
|
||||||
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.79 3.79.1 3.80),)
|
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.77 3.78 3.78.1 3.79 3.79.1 3.80),)
|
||||||
$(error GNU make 3.81 or better is required)
|
$(error GNU make 3.81 or better is required)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef srcdir
|
||||||
|
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||||
|
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
||||||
|
endif
|
||||||
|
ifndef top_srcdir
|
||||||
|
top_srcdir := $(srcdir)/../..
|
||||||
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
|
|
||||||
# update $PATH for our special stub build tools
|
# update $PATH for our special stub build tools
|
||||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||||
export PATH := $(HOME)/local/bin/bin-upx:$(PATH)
|
export PATH := $(HOME)/local/bin/bin-upx:$(PATH)
|
||||||
@@ -35,14 +44,6 @@ endif
|
|||||||
# //
|
# //
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
ifndef srcdir
|
|
||||||
srcdir := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
|
||||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
|
||||||
endif
|
|
||||||
ifndef top_srcdir
|
|
||||||
top_srcdir := $(srcdir)/../..
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef STUBS
|
ifndef STUBS
|
||||||
STUBS += amd64-linux.elf-entry.h
|
STUBS += amd64-linux.elf-entry.h
|
||||||
STUBS += amd64-linux.elf-fold.h
|
STUBS += amd64-linux.elf-fold.h
|
||||||
@@ -55,6 +56,8 @@ STUBS += arm-linux.kernel.vmlinux.h
|
|||||||
STUBS += arm-linux.kernel.vmlinux-head.h
|
STUBS += arm-linux.kernel.vmlinux-head.h
|
||||||
STUBS += armeb-linux.elf-entry.h
|
STUBS += armeb-linux.elf-entry.h
|
||||||
STUBS += armeb-linux.elf-fold.h
|
STUBS += armeb-linux.elf-fold.h
|
||||||
|
STUBS += armeb-linux.kernel.vmlinux.h
|
||||||
|
STUBS += armeb-linux.kernel.vmlinux-head.h
|
||||||
STUBS += arm.v4a-wince.pe.h
|
STUBS += arm.v4a-wince.pe.h
|
||||||
STUBS += arm.v4t-wince.pe.h
|
STUBS += arm.v4t-wince.pe.h
|
||||||
STUBS += i086-dos16.com.h
|
STUBS += i086-dos16.com.h
|
||||||
@@ -64,6 +67,8 @@ STUBS += i386-bsd.elf-entry.h
|
|||||||
STUBS += i386-bsd.elf-fold.h
|
STUBS += i386-bsd.elf-fold.h
|
||||||
STUBS += i386-bsd.elf.execve-entry.h
|
STUBS += i386-bsd.elf.execve-entry.h
|
||||||
STUBS += i386-bsd.elf.execve-fold.h
|
STUBS += i386-bsd.elf.execve-fold.h
|
||||||
|
STUBS += i386-darwin.macho-entry.h
|
||||||
|
STUBS += i386-darwin.macho-fold.h
|
||||||
STUBS += i386-openbsd.elf-fold.h
|
STUBS += i386-openbsd.elf-fold.h
|
||||||
STUBS += i386-dos32.djgpp2.h
|
STUBS += i386-dos32.djgpp2.h
|
||||||
STUBS += i386-dos32.djgpp2-stubify.h
|
STUBS += i386-dos32.djgpp2-stubify.h
|
||||||
@@ -101,14 +106,16 @@ default: $$(default.targets)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
all.targets ?= .upx-stubtools-stamp tmp/.tmp-stamp .all-stamp
|
all.targets ?= .upx-stubtools-stamp tmp/.tmp-stamp .all-stamp
|
||||||
all: $$(all.targets)
|
all: $$(all.targets)
|
||||||
.upx-stubtools-stamp: $(MAKEFILE_LIST)
|
.upx-stubtools-stamp: $(MAKEFILE_LIST)
|
||||||
upx-stubtools-check-version 20060823
|
upx-stubtools-check-version 20060823
|
||||||
@echo "timestamp" > $@
|
@echo "timestamp" > $@
|
||||||
tmp/.tmp-stamp:
|
%/.tmp-stamp:
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
@echo "timestamp" > $@
|
@echo "timestamp" > $@
|
||||||
|
.PRECIOUS: %/.tmp-stamp
|
||||||
.all-stamp: $$(STUBS)
|
.all-stamp: $$(STUBS)
|
||||||
@echo "timestamp" > $@
|
@echo "timestamp" > $@
|
||||||
|
|
||||||
@@ -131,13 +138,6 @@ maintainer-clean:
|
|||||||
# util var for use in the rules - basename of the current target
|
# util var for use in the rules - basename of the current target
|
||||||
override T = $(basename $(notdir $@))
|
override T = $(basename $(notdir $@))
|
||||||
|
|
||||||
# trim (strip) trailing whitespace
|
|
||||||
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
|
||||||
# squeeze duplicate blank lines, delete empty first & last line
|
|
||||||
BLSQUEEZE := $(RTRIM) | cat --squeeze-blank | sed -e '1{/^$$/d}' -e '$${/^$$/d}'
|
|
||||||
# delete blank lines
|
|
||||||
BLDEL := $(RTRIM) | sed -e '/^$$/d'
|
|
||||||
|
|
||||||
# clear some vars, just in case
|
# clear some vars, just in case
|
||||||
LABEL_PREFIX =
|
LABEL_PREFIX =
|
||||||
PP_FLAGS =
|
PP_FLAGS =
|
||||||
@@ -146,6 +146,21 @@ tc_bfdname =
|
|||||||
tc_list =
|
tc_list =
|
||||||
tc_objdump_disasm_options =
|
tc_objdump_disasm_options =
|
||||||
|
|
||||||
|
# commands
|
||||||
|
PYTHON = python
|
||||||
|
UNIX2DOS := perl -i -pe 's/$$/\r/;'
|
||||||
|
|
||||||
|
# trim (strip) trailing whitespace
|
||||||
|
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||||
|
# squeeze duplicate blank lines, delete empty first & last line
|
||||||
|
BLSQUEEZE := $(RTRIM) | cat --squeeze-blank | sed -e '1{/^$$/d}' -e '$${/^$$/d}'
|
||||||
|
# delete blank lines
|
||||||
|
BLDEL := $(RTRIM) | sed -e '/^$$/d'
|
||||||
|
# delete blank lines at top (beginning) of file
|
||||||
|
BLDELTOP := sed -e '/./,$$!d'
|
||||||
|
# delete blank lines at bottom (end) of file
|
||||||
|
BLDELBOT := sed -e ':a' -e '/^\n*$$/{$$d;N;ba' -e '}'
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // setup toolchain globals
|
# // setup toolchain globals
|
||||||
@@ -165,17 +180,18 @@ define tc
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
# default tools
|
# default tools
|
||||||
tc.default.bin2h = python $(top_srcdir)/src/stub/scripts/bin2h.py --ident=auto-stub
|
tc.default.bin2h = $(PYTHON) $(top_srcdir)/src/stub/scripts/bin2h.py --ident=auto-stub
|
||||||
##tc.default.bin2h-c = $(call tc,bin2h) --compress=14,15,0
|
##tc.default.bin2h-c = $(call tc,bin2h) --compress=14,15,0
|
||||||
tc.default.bin2h-c = $(call tc,bin2h) --compress=0
|
tc.default.bin2h-c = $(call tc,bin2h) --compress=0
|
||||||
tc.default.brandelf = python $(top_srcdir)/src/stub/scripts/brandelf.py $(if $(tc_bfdname),--bfdname=$(tc_bfdname))
|
tc.default.brandelf = $(PYTHON) $(top_srcdir)/src/stub/scripts/brandelf.py $(if $(tc_bfdname),--bfdname=$(tc_bfdname))
|
||||||
tc.default.gpp_inc = python $(top_srcdir)/src/stub/scripts/gpp_inc.py
|
tc.default.gpp_inc = $(PYTHON) $(top_srcdir)/src/stub/scripts/gpp_inc.py
|
||||||
tc.default.gpp_mkdep = python $(top_srcdir)/src/stub/scripts/gpp_inc.py -o /dev/null
|
tc.default.gpp_mkdep = $(PYTHON) $(top_srcdir)/src/stub/scripts/gpp_inc.py -o /dev/null
|
||||||
tc.default.pp-as = i386-linux-gcc-3.4.6 -E -nostdinc -x assembler-with-cpp -Wall
|
tc.default.pp-as = i386-linux-gcc-3.4.6 -E -nostdinc -x assembler-with-cpp -Wall
|
||||||
tc.default.sstrip = sstrip
|
tc.default.sstrip = sstrip
|
||||||
tc.default.xstrip = python $(top_srcdir)/src/stub/scripts/xstrip.py
|
tc.default.xstrip = $(PYTHON) $(top_srcdir)/src/stub/scripts/xstrip.py
|
||||||
|
|
||||||
# default multiarch-binutils
|
# default multiarch-binutils
|
||||||
|
tc.default.m-ar = multiarch-ar-2.17
|
||||||
tc.default.m-ld = multiarch-ld-2.17 $(if $(tc_bfdname),-b $(tc_bfdname))
|
tc.default.m-ld = multiarch-ld-2.17 $(if $(tc_bfdname),-b $(tc_bfdname))
|
||||||
tc.default.m-nm = multiarch-nm-2.17 $(if $(tc_bfdname),--target=$(tc_bfdname))
|
tc.default.m-nm = multiarch-nm-2.17 $(if $(tc_bfdname),--target=$(tc_bfdname))
|
||||||
tc.default.m-objcopy = multiarch-objcopy-2.17 $(if $(tc_bfdname),-F $(tc_bfdname))
|
tc.default.m-objcopy = multiarch-objcopy-2.17 $(if $(tc_bfdname),-F $(tc_bfdname))
|
||||||
@@ -207,6 +223,7 @@ endef
|
|||||||
|
|
||||||
# some common arch settings
|
# some common arch settings
|
||||||
tc.arch-i086.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@
|
tc.arch-i086.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@
|
||||||
|
tc.arch-i086.wdis = $(WATCOM)/binl/wdis
|
||||||
tc.arch-i386.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@
|
tc.arch-i386.gcc = i386-linux-gcc-3.4.6 -m32 -march=i386 -nostdinc -MMD -MT $@
|
||||||
tc.arch-i386.djasm = djasm
|
tc.arch-i386.djasm = djasm
|
||||||
|
|
||||||
@@ -321,6 +338,28 @@ arm-linux.kernel.vmlinux-head.h : $(srcdir)/src/$$T.S
|
|||||||
$(call tc,bin2h) tmp/$T.bin $@
|
$(call tc,bin2h) tmp/$T.bin $@
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // armeb-linux.kernel.vmlinux
|
||||||
|
# // armeb-linux.kernel.vmlinuz
|
||||||
|
# // armeb-linux.kernel.vmlinux-head
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
armeb-linux.kernel.vmlinu%.h : tc_list = armeb-linux.kernel default
|
||||||
|
armeb-linux.kernel.vmlinu%.h : tc_bfdname = elf32-bigarm
|
||||||
|
|
||||||
|
tc.armeb-linux.kernel.gcc = $(tc.arm-linux.elf.gcc) -mbig-endian
|
||||||
|
|
||||||
|
armeb-linux.kernel.vmlinu%.h : $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin
|
||||||
|
$(call tc,f-embed_objinfo,tmp/$T.bin)
|
||||||
|
$(call tc,bin2h-c) tmp/$T.bin $@
|
||||||
|
|
||||||
|
armeb-linux.kernel.vmlinux-head.h : $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.o
|
||||||
|
$(call tc,objcopy) --output-target binary --only-section .text tmp/$T.o tmp/$T.bin
|
||||||
|
$(call tc,bin2h) tmp/$T.bin $@
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // armeb-linux.elf
|
# // armeb-linux.elf
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
@@ -507,6 +546,34 @@ tmp/i386-bsd.elf.execve-upx_itoa.o : $(srcdir)/src/$$T.S
|
|||||||
$(call tc,f-objstrip,$@)
|
$(call tc,f-objstrip,$@)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // i386-darwin.macho
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
# info: we use the tc settings from i386-linux.elf
|
||||||
|
i386-darwin.macho%.h : tc_list = i386-linux.elf default
|
||||||
|
i386-darwin.macho%.h : tc_bfdname = elf32-i386
|
||||||
|
|
||||||
|
i386-darwin.macho-entry.h : $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c $< -o tmp/$T.bin
|
||||||
|
$(call tc,f-embed_objinfo,tmp/$T.bin)
|
||||||
|
$(call tc,bin2h) tmp/$T.bin $@
|
||||||
|
|
||||||
|
i386-darwin.macho-fold.h : tmp/$$T.o tmp/i386-darwin.macho-main.o
|
||||||
|
$(call tc,ld) --no-warn-mismatch --strip-all --oformat binary -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.bin
|
||||||
|
chmod a-x tmp/$T.bin
|
||||||
|
$(call tc,bin2h) tmp/$T.bin $@
|
||||||
|
|
||||||
|
tmp/i386-darwin.macho-fold.o : $(srcdir)/src/$$T.S
|
||||||
|
$(call tc,gcc) -c $< -o $@
|
||||||
|
$(call tc,f-objstrip,$@)
|
||||||
|
|
||||||
|
tmp/i386-darwin.macho-main.o : $(srcdir)/src/$$T.c
|
||||||
|
$(call tc,gcc) -c -Os $< -o $@
|
||||||
|
$(call tc,f-objstrip,$@)
|
||||||
|
$(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // i386-dos32.djgpp2
|
# // i386-dos32.djgpp2
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_ARM_LINUX_ELF_ENTRY_SIZE 16296
|
#define STUB_ARM_LINUX_ELF_ENTRY_SIZE 16296
|
||||||
#define STUB_ARM_LINUX_ELF_ENTRY_ADLER32 0x9b815c2e
|
#define STUB_ARM_LINUX_ELF_ENTRY_ADLER32 0xdf115bee
|
||||||
#define STUB_ARM_LINUX_ELF_ENTRY_CRC32 0x3b801af9
|
#define STUB_ARM_LINUX_ELF_ENTRY_CRC32 0x8704e1a1
|
||||||
|
|
||||||
unsigned char stub_arm_linux_elf_entry[16296] = {
|
unsigned char stub_arm_linux_elf_entry[16296] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
@@ -44,7 +44,7 @@ unsigned char stub_arm_linux_elf_entry[16296] = {
|
|||||||
254, 1,160,232, 15, 0, 0, 58, 9, 64, 64,224, 80, 80,143,226, /* 0x 80 */
|
254, 1,160,232, 15, 0, 0, 58, 9, 64, 64,224, 80, 80,143,226, /* 0x 80 */
|
||||||
0,224,160,225, 4, 80,133,224, 5, 0,160,225, 4, 16,137,224, /* 0x 90 */
|
0,224,160,225, 4, 80,133,224, 5, 0,160,225, 4, 16,137,224, /* 0x 90 */
|
||||||
0, 32,160,227, 2, 0,159,239, 0,144,156,229,140,144, 73,226, /* 0x a0 */
|
0, 32,160,227, 2, 0,159,239, 0,144,156,229,140,144, 73,226, /* 0x a0 */
|
||||||
9,160, 76,224, 4,160,138,224, 8, 0,219,229, 1, 64, 45,233, /* 0x b0 */
|
9,160, 76,224, 4,160,138,224, 8, 0,155,229, 1, 64, 45,233, /* 0x b0 */
|
||||||
0, 48,155,229, 12, 0,139,226, 4, 16,155,229, 14, 32,160,225, /* 0x c0 */
|
0, 48,155,229, 12, 0,139,226, 4, 16,155,229, 14, 32,160,225, /* 0x c0 */
|
||||||
8, 48,141,229, 8, 48,141,226, 15,224,160,225, 5,240,160,225, /* 0x d0 */
|
8, 48,141,229, 8, 48,141,226, 15,224,160,225, 5,240,160,225, /* 0x d0 */
|
||||||
2,128,189,232,252, 64, 45,233, 0,112,129,224, 0, 80,224,227, /* 0x e0 */
|
2,128,189,232,252, 64, 45,233, 0,112,129,224, 0, 80,224,227, /* 0x e0 */
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_ARM_LINUX_KERNEL_VMLINUX_SIZE 17091
|
#define STUB_ARM_LINUX_KERNEL_VMLINUX_SIZE 17091
|
||||||
#define STUB_ARM_LINUX_KERNEL_VMLINUX_ADLER32 0x3d6cea16
|
#define STUB_ARM_LINUX_KERNEL_VMLINUX_ADLER32 0x2af6ea3d
|
||||||
#define STUB_ARM_LINUX_KERNEL_VMLINUX_CRC32 0xab8eacad
|
#define STUB_ARM_LINUX_KERNEL_VMLINUX_CRC32 0x12d16cc6
|
||||||
|
|
||||||
unsigned char stub_arm_linux_kernel_vmlinux[17091] = {
|
unsigned char stub_arm_linux_kernel_vmlinux[17091] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
@@ -570,7 +570,7 @@ unsigned char stub_arm_linux_kernel_vmlinux[17091] = {
|
|||||||
10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, /* 0x2160 */
|
10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, /* 0x2160 */
|
||||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, /* 0x2170 */
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, /* 0x2170 */
|
||||||
69, 10, 48, 48, 48, 48, 48, 48, 49, 52, 32, 82, 95, 65, 82, 77, /* 0x2180 */
|
69, 10, 48, 48, 48, 48, 48, 48, 49, 52, 32, 82, 95, 65, 82, 77, /* 0x2180 */
|
||||||
95, 65, 66, 83, 56, 32, 32, 32, 32, 32, 32, 32, 32, 77, 69, 84, /* 0x2190 */
|
95, 65, 66, 83, 51, 50, 32, 32, 32, 32, 32, 32, 32, 77, 69, 84, /* 0x2190 */
|
||||||
72, 79, 68, 10, 48, 48, 48, 48, 48, 48, 51, 48, 32, 82, 95, 65, /* 0x21a0 */
|
72, 79, 68, 10, 48, 48, 48, 48, 48, 48, 51, 48, 32, 82, 95, 65, /* 0x21a0 */
|
||||||
82, 77, 95, 80, 67, 50, 52, 32, 32, 32, 32, 32, 32, 32, 32, 76, /* 0x21b0 */
|
82, 77, 95, 80, 67, 50, 52, 32, 32, 32, 32, 32, 32, 32, 32, 76, /* 0x21b0 */
|
||||||
73, 78, 85, 88, 48, 51, 48, 10, 48, 48, 48, 48, 48, 48, 51, 52, /* 0x21c0 */
|
73, 78, 85, 88, 48, 51, 48, 10, 48, 48, 48, 48, 48, 48, 51, 52, /* 0x21c0 */
|
||||||
@@ -589,9 +589,9 @@ unsigned char stub_arm_linux_kernel_vmlinux[17091] = {
|
|||||||
79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, /* 0x2290 */
|
79, 70, 70, 83, 69, 84, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, /* 0x2290 */
|
||||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, /* 0x22a0 */
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, /* 0x22a0 */
|
||||||
10, 48, 48, 48, 48, 48, 48, 48, 56, 32, 82, 95, 65, 82, 77, 95, /* 0x22b0 */
|
10, 48, 48, 48, 48, 48, 48, 48, 56, 32, 82, 95, 65, 82, 77, 95, /* 0x22b0 */
|
||||||
65, 66, 83, 56, 32, 32, 32, 32, 32, 32, 32, 32,102,105,108,116, /* 0x22c0 */
|
65, 66, 83, 51, 50, 32, 32, 32, 32, 32, 32, 32,102,105,108,116, /* 0x22c0 */
|
||||||
101,114, 95, 99,116,111, 10, 48, 48, 48, 48, 48, 48, 48, 99, 32, /* 0x22d0 */
|
101,114, 95, 99,116,111, 10, 48, 48, 48, 48, 48, 48, 48, 99, 32, /* 0x22d0 */
|
||||||
82, 95, 65, 82, 77, 95, 65, 66, 83, 56, 32, 32, 32, 32, 32, 32, /* 0x22e0 */
|
82, 95, 65, 82, 77, 95, 65, 66, 83, 51, 50, 32, 32, 32, 32, 32, /* 0x22e0 */
|
||||||
32, 32,102,105,108,116,101,114, 95,105,100, 10, 48, 48, 48, 48, /* 0x22f0 */
|
32, 32,102,105,108,116,101,114, 95,105,100, 10, 48, 48, 48, 48, /* 0x22f0 */
|
||||||
48, 48, 49, 48, 32, 82, 95, 65, 82, 77, 95, 80, 67, 50, 52, 32, /* 0x2300 */
|
48, 48, 49, 48, 32, 82, 95, 65, 82, 77, 95, 80, 67, 50, 52, 32, /* 0x2300 */
|
||||||
32, 32, 32, 32, 32, 32, 32, 99,116,111,107, 51, 50, 46, 48, 48, /* 0x2310 */
|
32, 32, 32, 32, 32, 32, 32, 99,116,111,107, 51, 50, 46, 48, 48, /* 0x2310 */
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_ARMEB_LINUX_ELF_ENTRY_SIZE 16295
|
#define STUB_ARMEB_LINUX_ELF_ENTRY_SIZE 16295
|
||||||
#define STUB_ARMEB_LINUX_ELF_ENTRY_ADLER32 0x87435b9a
|
#define STUB_ARMEB_LINUX_ELF_ENTRY_ADLER32 0xcad35b5a
|
||||||
#define STUB_ARMEB_LINUX_ELF_ENTRY_CRC32 0x7cf93476
|
#define STUB_ARMEB_LINUX_ELF_ENTRY_CRC32 0xc07dcf2e
|
||||||
|
|
||||||
unsigned char stub_armeb_linux_elf_entry[16295] = {
|
unsigned char stub_armeb_linux_elf_entry[16295] = {
|
||||||
127, 69, 76, 70, 1, 2, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 2, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
@@ -44,7 +44,7 @@ unsigned char stub_armeb_linux_elf_entry[16295] = {
|
|||||||
232,160, 1,254, 58, 0, 0, 15,224, 64, 64, 9,226,143, 80, 80, /* 0x 80 */
|
232,160, 1,254, 58, 0, 0, 15,224, 64, 64, 9,226,143, 80, 80, /* 0x 80 */
|
||||||
225,160,224, 0,224,133, 80, 4,225,160, 0, 5,224,137, 16, 4, /* 0x 90 */
|
225,160,224, 0,224,133, 80, 4,225,160, 0, 5,224,137, 16, 4, /* 0x 90 */
|
||||||
227,160, 32, 0,239,159, 0, 2,229,156,144, 0,226, 73,144,140, /* 0x a0 */
|
227,160, 32, 0,239,159, 0, 2,229,156,144, 0,226, 73,144,140, /* 0x a0 */
|
||||||
224, 76,160, 9,224,138,160, 4,229,219, 0, 8,233, 45, 64, 1, /* 0x b0 */
|
224, 76,160, 9,224,138,160, 4,229,155, 0, 8,233, 45, 64, 1, /* 0x b0 */
|
||||||
229,155, 48, 0,226,139, 0, 12,229,155, 16, 4,225,160, 32, 14, /* 0x c0 */
|
229,155, 48, 0,226,139, 0, 12,229,155, 16, 4,225,160, 32, 14, /* 0x c0 */
|
||||||
229,141, 48, 8,226,141, 48, 8,225,160,224, 15,225,160,240, 5, /* 0x d0 */
|
229,141, 48, 8,226,141, 48, 8,225,160,224, 15,225,160,240, 5, /* 0x d0 */
|
||||||
232,189,128, 2,233, 45, 64,252,224,129,112, 0,227,224, 80, 0, /* 0x e0 */
|
232,189,128, 2,233, 45, 64,252,224,129,112, 0,227,224, 80, 0, /* 0x e0 */
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* armeb-linux.kernel.vmlinux-head.h
|
||||||
|
created from armeb-linux.kernel.vmlinux-head.bin, 8 (0x8) bytes
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2007 Laszlo Molnar
|
||||||
|
Copyright (C) 2000-2007 John F. Reiser
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define STUB_ARMEB_LINUX_KERNEL_VMLINUX_HEAD_SIZE 8
|
||||||
|
#define STUB_ARMEB_LINUX_KERNEL_VMLINUX_HEAD_ADLER32 0x19db0637
|
||||||
|
#define STUB_ARMEB_LINUX_KERNEL_VMLINUX_HEAD_CRC32 0xb5ec5990
|
||||||
|
|
||||||
|
unsigned char stub_armeb_linux_kernel_vmlinux_head[8] = {
|
||||||
|
225,160,192, 14,235,255,255,254 /* 0x 0 */
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
+1915
-817
File diff suppressed because it is too large
Load Diff
@@ -29,15 +29,15 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_I386_BSD_ELF_ENTRY_SIZE 37562
|
#define STUB_I386_BSD_ELF_ENTRY_SIZE 37562
|
||||||
#define STUB_I386_BSD_ELF_ENTRY_ADLER32 0xb6d5917d
|
#define STUB_I386_BSD_ELF_ENTRY_ADLER32 0x0c31915d
|
||||||
#define STUB_I386_BSD_ELF_ENTRY_CRC32 0x57a02d3a
|
#define STUB_I386_BSD_ELF_ENTRY_CRC32 0x68fd1b14
|
||||||
|
|
||||||
unsigned char stub_i386_bsd_elf_entry[37562] = {
|
unsigned char stub_i386_bsd_elf_entry[37562] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
1, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 10 */
|
1, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 10 */
|
||||||
116, 34, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 40, 0, /* 0x 20 */
|
116, 34, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 40, 0, /* 0x 20 */
|
||||||
243, 0,240, 0,232,123, 0, 0, 0, 96,139,116, 36, 40,139,124, /* 0x 30 */
|
243, 0,240, 0,232,123, 0, 0, 0, 96,139,116, 36, 36,139,124, /* 0x 30 */
|
||||||
36, 48,131,205,255,235, 3,164,235, 3,138, 6, 70,136, 7, 71, /* 0x 40 */
|
36, 44,131,205,255,235, 3,164,235, 3,138, 6, 70,136, 7, 71, /* 0x 40 */
|
||||||
1,219,117, 7,139, 30,131,238,252, 17,219,114, 1, 49,192, 64, /* 0x 50 */
|
1,219,117, 7,139, 30,131,238,252, 17,219,114, 1, 49,192, 64, /* 0x 50 */
|
||||||
138, 7,114,255,184, 1, 0, 0, 0, 1,219,117, 7,139, 30,131, /* 0x 60 */
|
138, 7,114,255,184, 1, 0, 0, 0, 1,219,117, 7,139, 30,131, /* 0x 60 */
|
||||||
238,252, 17,219, 17,192, 1,219,117, 7,139, 30,131,238,252, 17, /* 0x 70 */
|
238,252, 17,219, 17,192, 1,219,117, 7,139, 30,131,238,252, 17, /* 0x 70 */
|
||||||
@@ -88,10 +88,10 @@ unsigned char stub_i386_bsd_elf_entry[37562] = {
|
|||||||
4,119,241, 1,207,233,252,255,255,255,137,229,141,156, 36, 0, /* 0x 340 */
|
4,119,241, 1,207,233,252,255,255,255,137,229,141,156, 36, 0, /* 0x 340 */
|
||||||
0, 0, 0, 49,192, 80, 57,220,117,251, 70, 70, 83,104, 0, 0, /* 0x 350 */
|
0, 0, 0, 49,192, 80, 57,220,117,251, 70, 70, 83,104, 0, 0, /* 0x 350 */
|
||||||
0, 0, 87,131,195, 4, 83,104, 0, 0, 0, 0, 86,131,195, 4, /* 0x 360 */
|
0, 0, 87,131,195, 4, 83,104, 0, 0, 0, 0, 86,131,195, 4, /* 0x 360 */
|
||||||
83, 80,199, 3, 0, 0, 0, 0,137,229,139, 85, 44,172, 74,136, /* 0x 370 */
|
83, 80,199, 3, 0, 0, 0, 0,137,229,139, 85, 40,172, 74,136, /* 0x 370 */
|
||||||
193, 36, 7,192,233, 3,187, 0,253,255,255,211,227,141,164, 92, /* 0x 380 */
|
193, 36, 7,192,233, 3,187, 0,253,255,255,211,227,141,164, 92, /* 0x 380 */
|
||||||
144,241,255,255,131,228,224,106, 0,106, 0,137,227, 83,131,195, /* 0x 390 */
|
144,241,255,255,131,228,224,106, 0,106, 0,137,227, 83,131,195, /* 0x 390 */
|
||||||
4,139, 77, 52,255, 49, 87, 83,131,195, 4,136, 67, 2,172, 74, /* 0x 3a0 */
|
4,139, 77, 48,255, 49, 87, 83,131,195, 4,136, 67, 2,172, 74, /* 0x 3a0 */
|
||||||
136,193, 36, 15,136, 3,192,233, 4,136, 75, 1, 82, 86, 83, 80, /* 0x 3b0 */
|
136,193, 36, 15,136, 3,192,233, 4,136, 75, 1, 82, 86, 83, 80, /* 0x 3b0 */
|
||||||
85, 87, 86, 83,131,236,124,139,148, 36,144, 0, 0, 0,199, 68, /* 0x 3c0 */
|
85, 87, 86, 83,131,236,124,139,148, 36,144, 0, 0, 0,199, 68, /* 0x 3c0 */
|
||||||
36,116, 0, 0, 0, 0,198, 68, 36,115, 0,139,172, 36,156, 0, /* 0x 3d0 */
|
36,116, 0, 0, 0, 0,198, 68, 36,115, 0,139,172, 36,156, 0, /* 0x 3d0 */
|
||||||
@@ -431,8 +431,8 @@ unsigned char stub_i386_bsd_elf_entry[37562] = {
|
|||||||
148, 36,156, 0, 0, 0,139, 76, 36,116,137, 26,139,156, 36,168, /* 0x18b0 */
|
148, 36,156, 0, 0, 0,139, 76, 36,116,137, 26,139,156, 36,168, /* 0x18b0 */
|
||||||
0, 0, 0,137, 11,131,196,124, 91, 94, 95, 93, 3,115,252, 3, /* 0x18c0 */
|
0, 0, 0,137, 11,131,196,124, 91, 94, 95, 93, 3,115,252, 3, /* 0x18c0 */
|
||||||
123,248, 49,192,141,140, 36, 0,255,255,255,137,236, 80, 57,204, /* 0x18d0 */
|
123,248, 49,192,141,140, 36, 0,255,255,255,137,236, 80, 57,204, /* 0x18d0 */
|
||||||
117,251,137,236, 49,201,139, 84, 36, 40, 3, 84, 36, 44, 57,214, /* 0x18e0 */
|
117,251,137,236, 49,201,139, 84, 36, 36, 3, 84, 36, 40, 57,214, /* 0x18e0 */
|
||||||
116, 1, 72, 43,124, 36, 48,139, 84, 36, 52,137, 58,137, 68, 36, /* 0x18f0 */
|
116, 1, 72, 43,124, 36, 44,139, 84, 36, 48,137, 58,137, 68, 36, /* 0x18f0 */
|
||||||
28, 97,195,235, 4, 90, 88, 89,151, 96, 49,219,187, 0, 0, 0, /* 0x1900 */
|
28, 97,195,235, 4, 90, 88, 89,151, 96, 49,219,187, 0, 0, 0, /* 0x1900 */
|
||||||
0,106, 15, 88,138,100, 36, 32,106, 15, 91,138,124, 36, 32,138, /* 0x1910 */
|
0,106, 15, 88,138,100, 36, 32,106, 15, 91,138,124, 36, 32,138, /* 0x1910 */
|
||||||
84, 36, 32,233,252,255,255,255, 15,183, 47, 43,110, 12, 41,221, /* 0x1920 */
|
84, 36, 32,233,252,255,255,255, 15,183, 47, 43,110, 12, 41,221, /* 0x1920 */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,106 @@
|
|||||||
|
/* i386-darwin.macho-fold.h
|
||||||
|
created from i386-darwin.macho-fold.bin, 1105 (0x451) bytes
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2007 Laszlo Molnar
|
||||||
|
Copyright (C) 2000-2007 John F. Reiser
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define STUB_I386_DARWIN_MACHO_FOLD_SIZE 1105
|
||||||
|
#define STUB_I386_DARWIN_MACHO_FOLD_ADLER32 0x5ad106a1
|
||||||
|
#define STUB_I386_DARWIN_MACHO_FOLD_CRC32 0x01a4878b
|
||||||
|
|
||||||
|
unsigned char stub_i386_darwin_macho_fold[1105] = {
|
||||||
|
106, 0,137,231,141,117, 2,139, 19,137,217, 41,209,139, 89, 24, /* 0x 0 */
|
||||||
|
184, 0, 8, 0, 0, 57,216,118, 2,137,195, 41,220, 96,232, 6, /* 0x 10 */
|
||||||
|
3, 0, 0,139, 76, 36, 16,141,100, 12, 32,255, 96, 40,139, 68, /* 0x 20 */
|
||||||
|
36, 4,139, 76, 36, 8,139, 16, 15,202,137, 16,131,233, 4,141, /* 0x 30 */
|
||||||
|
64, 4,115,242,195, 90, 15, 52,176, 1,235, 2,176, 74,235, 2, /* 0x 40 */
|
||||||
|
176, 73,235, 2,176,153,235, 2,176, 6,235, 2,176, 5,235, 2, /* 0x 50 */
|
||||||
|
176,197,235, 2,176, 3, 15,182,192,137,225,232,213,255,255,255, /* 0x 60 */
|
||||||
|
115, 3,131,200,255,195,144,144, 85,137,229, 87, 86,139,125, 8, /* 0x 70 */
|
||||||
|
83,137,195, 57, 56,139,112, 4,115, 7,106,127,232,183,255,255, /* 0x 80 */
|
||||||
|
255,133,255,116, 10,137,249,138, 6, 70,136, 2, 66,226,248, 1, /* 0x 90 */
|
||||||
|
123, 4, 41, 59,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, /* 0x a0 */
|
||||||
|
86,137,198, 83,137,211,131,236, 24,139, 69, 8,139,125, 12,137, /* 0x b0 */
|
||||||
|
69,220,131, 58, 0, 15,132,172, 0, 0, 0,141, 85,228,137,240, /* 0x c0 */
|
||||||
|
106, 12,232,161,255,255,255,139, 69,228, 90,133,192,139, 77,232, /* 0x d0 */
|
||||||
|
117, 19,129,249, 85, 80, 88, 33,117, 15,131, 62, 0, 15,132,132, /* 0x e0 */
|
||||||
|
0, 0, 0,235, 4,133,201,117, 7,106,127,232, 72,255,255,255, /* 0x f0 */
|
||||||
|
57,193,119,245, 59, 3,119,241, 57,193,115, 76,137, 69,224, 15, /* 0x 100 */
|
||||||
|
182, 69,236, 80,141, 69,224, 80,255,115, 4, 81,255,118, 4,255, /* 0x 110 */
|
||||||
|
85,220,131,196, 20,133,192,117,208,139, 85,224, 59, 85,228,117, /* 0x 120 */
|
||||||
|
200,138, 69,237,132,192,116, 22,133,255,116, 18, 15,182,192, 80, /* 0x 130 */
|
||||||
|
15,182, 69,238, 80, 82,255,115, 4,255,215,131,196, 16,139, 69, /* 0x 140 */
|
||||||
|
232, 1, 70, 4, 41, 6,235, 12,139, 83, 4, 81,137,240,232, 21, /* 0x 150 */
|
||||||
|
255,255,255, 88,139, 85,228,139, 3, 1, 83, 4, 41,208,133,192, /* 0x 160 */
|
||||||
|
137, 3,233, 78,255,255,255,141,101,244, 91, 94, 95,201,195, 85, /* 0x 170 */
|
||||||
|
137,229, 87, 86, 83,131,236, 48,137, 69,232,139, 69, 8,137, 85, /* 0x 180 */
|
||||||
|
228,139, 85, 12,199, 69,208, 0, 0, 0, 0,137, 69,224,139, 69, /* 0x 190 */
|
||||||
|
20,137, 85,220,139, 85, 24,137, 69,216,139, 93,232,139, 69,232, /* 0x 1a0 */
|
||||||
|
137, 85,212, 49,210,131,195, 28,199, 69,204, 0, 0, 0, 0, 59, /* 0x 1b0 */
|
||||||
|
80, 16, 15,131, 86, 1, 0, 0,139, 3,131,248, 1, 15,133, 29, /* 0x 1c0 */
|
||||||
|
1, 0, 0,139, 83, 24,139, 67, 28,139, 75, 36,137,214, 1,208, /* 0x 1d0 */
|
||||||
|
137, 85,240,137, 69,200,137,208, 37,255, 15, 0, 0,137,207, 41, /* 0x 1e0 */
|
||||||
|
198, 1,199,137, 77,236,116, 69,139, 69,228, 49,210, 3, 67, 32, /* 0x 1f0 */
|
||||||
|
82,133,201, 80,139, 69,220,117, 3,131,200,255,131,125,224, 0, /* 0x 200 */
|
||||||
|
80,117, 9,133,201,184, 18, 0, 0, 0,117, 5,184, 18, 16, 0, /* 0x 210 */
|
||||||
|
0,131,125,224, 0, 80,106, 3,137,248,116, 3,141, 71, 3, 80, /* 0x 220 */
|
||||||
|
86,232, 42,254,255,255,131,196, 28, 57,198,117, 94,131,125,224, /* 0x 230 */
|
||||||
|
0,116, 42,131,123, 36, 0,116, 36,131,123, 32, 0,117, 11,131, /* 0x 240 */
|
||||||
|
125, 16, 0,116, 5,139, 85, 16,137, 50,255,117,212,255,117,216, /* 0x 250 */
|
||||||
|
141, 85,236,139, 69,224,232, 65,254,255,255, 88, 90,137,248,141, /* 0x 260 */
|
||||||
|
20, 62,247,216, 37,255, 15, 0, 0,137, 69,196,116, 8,137,193, /* 0x 270 */
|
||||||
|
198, 2, 0, 66,226,250,133,255,116, 24,255,115, 44, 87, 86,232, /* 0x 280 */
|
||||||
|
184,253,255,255,131,196, 12,133,192,116, 7,106,127,232,166,253, /* 0x 290 */
|
||||||
|
255,255,139, 85,196,141, 4, 23, 1,198, 59,117,200,115, 35,106, /* 0x 2a0 */
|
||||||
|
0,106, 0,106,255,104, 18, 16, 0, 0,255,115, 44, 41,117,200, /* 0x 2b0 */
|
||||||
|
255,117,200, 86,232,151,253,255,255,131,196, 28, 57,198,116, 58, /* 0x 2c0 */
|
||||||
|
235,201,131,125,224, 0,116, 50,141, 71, 3, 37,255, 15, 0, 0, /* 0x 2d0 */
|
||||||
|
131,248, 3,119, 37, 80, 86,232,100,253,255,255, 89, 94,235, 26, /* 0x 2e0 */
|
||||||
|
131,232, 4,131,248, 1,119, 18,131,123, 8, 1,117, 12,131,123, /* 0x 2f0 */
|
||||||
|
12, 16,117, 6,141, 67, 16,137, 69,208,255, 69,204,139, 85,232, /* 0x 300 */
|
||||||
|
139, 69,204, 3, 91, 4, 59, 66, 16,233,164,254,255,255,139, 69, /* 0x 310 */
|
||||||
|
208,141,101,244, 91, 94, 95,201,195, 85,137,229, 87, 86, 83,131, /* 0x 320 */
|
||||||
|
236, 32,199, 69,212, 0, 0, 0, 0,139, 85, 32,139, 69, 24,139, /* 0x 330 */
|
||||||
|
93, 16,137, 69,216,139,117, 20,141, 66, 24,137,117,232,137, 69, /* 0x 340 */
|
||||||
|
240,139, 69, 28,131,232, 24,137, 69,236,139, 66, 24,139, 85,240, /* 0x 350 */
|
||||||
|
106, 0,137, 69,228,139, 69,236,137, 85,224,137, 69,220,141, 85, /* 0x 360 */
|
||||||
|
228,141, 69,236, 83,232, 50,253,255,255,255,117, 12, 83, 49,210, /* 0x 370 */
|
||||||
|
255,117, 8,141, 69,220,106,255, 80,137,240,232,239,253,255,255, /* 0x 380 */
|
||||||
|
49,210,137,195,141, 70, 28,131,196, 28,139, 78, 16, 57,202, 15, /* 0x 390 */
|
||||||
|
131,162, 0, 0, 0,131, 56, 14, 15,133,144, 0, 0, 0, 3, 64, /* 0x 3a0 */
|
||||||
|
8,106, 0,106, 0, 80,232,161,252,255,255,131,196, 12,133,192, /* 0x 3b0 */
|
||||||
|
137,199,120, 25, 49,210,139, 69,212, 82, 80,255,117,216, 86, 87, /* 0x 3c0 */
|
||||||
|
232,127,252,255,255,131,196, 20, 57, 69,216,116, 15,106,127,232, /* 0x 3d0 */
|
||||||
|
100,252,255,255,139, 91, 8,137, 93,212,235,216,129, 62,202,254, /* 0x 3e0 */
|
||||||
|
186,190,117, 42, 15,182, 70, 7,141, 94, 8,107,192, 20,131,192, /* 0x 3f0 */
|
||||||
|
8, 80, 86,232, 38,252,255,255, 89, 90, 49,192,139, 86, 4, 57, /* 0x 400 */
|
||||||
|
208,115, 11,131, 59, 7,116,204, 64,131,195, 20,235,241,106, 0, /* 0x 410 */
|
||||||
|
139, 85,212,106, 0,137,240,106, 0, 87,106, 0,232, 78,253,255, /* 0x 420 */
|
||||||
|
255, 87,137,195,232, 31,252,255,255,131,196, 24,235, 9, 3, 64, /* 0x 430 */
|
||||||
|
4, 66,233, 86,255,255,255,141,101,244,137,216, 91, 94, 95,201, /* 0x 440 */
|
||||||
|
195 /* 0x 450 */
|
||||||
|
};
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_I386_DOS32_TMT_SIZE 27032
|
#define STUB_I386_DOS32_TMT_SIZE 27032
|
||||||
#define STUB_I386_DOS32_TMT_ADLER32 0xe058a94c
|
#define STUB_I386_DOS32_TMT_ADLER32 0x60faa944
|
||||||
#define STUB_I386_DOS32_TMT_CRC32 0x76e13290
|
#define STUB_I386_DOS32_TMT_CRC32 0x1e38f90e
|
||||||
|
|
||||||
unsigned char stub_i386_dos32_tmt[27032] = {
|
unsigned char stub_i386_dos32_tmt[27032] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
@@ -444,7 +444,7 @@ unsigned char stub_i386_dos32_tmt[27032] = {
|
|||||||
0, 0,235, 30,138, 7,131,199, 1, 60,128,114, 10, 60,143,119, /* 0x1980 */
|
0, 0,235, 30,138, 7,131,199, 1, 60,128,114, 10, 60,143,119, /* 0x1980 */
|
||||||
6,128,127,254, 15,116, 5, 44,232, 60, 1,119,255,128, 63, 0, /* 0x1990 */
|
6,128,127,254, 15,116, 5, 44,232, 60, 1,119,255,128, 63, 0, /* 0x1990 */
|
||||||
117,255,139, 7,102,193,232, 8,193,192, 16,134,196, 41,248, 1, /* 0x19a0 */
|
117,255,139, 7,102,193,232, 8,193,192, 16,134,196, 41,248, 1, /* 0x19a0 */
|
||||||
240,137, 7,131,199, 4,131,233, 4,138, 7,131,199, 1,226, 13, /* 0x19b0 */
|
232,137, 7,131,199, 4,131,233, 4,138, 7,131,199, 1,226, 13, /* 0x19b0 */
|
||||||
131,233, 1,127, 6,141,125,252, 49,192,138, 6, 70, 9,192,116, /* 0x19c0 */
|
131,233, 1,127, 6,141,125,252, 49,192,138, 6, 70, 9,192,116, /* 0x19c0 */
|
||||||
1, 60,239,119, 17, 1,199,139, 7,134,196,193,192, 16,134,196, /* 0x19d0 */
|
1, 60,239,119, 17, 1,199,139, 7,134,196,193,192, 16,134,196, /* 0x19d0 */
|
||||||
1,232,137, 7,235,226, 36, 15,193,224, 16,102,139, 6,131,198, /* 0x19e0 */
|
1,232,137, 7,235,226, 36, 15,193,224, 16,102,139, 6,131,198, /* 0x19e0 */
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_I386_DOS32_WATCOM_LE_SIZE 27436
|
#define STUB_I386_DOS32_WATCOM_LE_SIZE 27436
|
||||||
#define STUB_I386_DOS32_WATCOM_LE_ADLER32 0x1fda144c
|
#define STUB_I386_DOS32_WATCOM_LE_ADLER32 0x946d1444
|
||||||
#define STUB_I386_DOS32_WATCOM_LE_CRC32 0xd84b8031
|
#define STUB_I386_DOS32_WATCOM_LE_CRC32 0x39b33888
|
||||||
|
|
||||||
unsigned char stub_i386_dos32_watcom_le[27436] = {
|
unsigned char stub_i386_dos32_watcom_le[27436] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
@@ -445,7 +445,7 @@ unsigned char stub_i386_dos32_watcom_le[27436] = {
|
|||||||
4,185, 0, 0, 0, 0,235, 30,138, 7,131,199, 1, 60,128,114, /* 0x1990 */
|
4,185, 0, 0, 0, 0,235, 30,138, 7,131,199, 1, 60,128,114, /* 0x1990 */
|
||||||
10, 60,143,119, 6,128,127,254, 15,116, 5, 44,232, 60, 1,119, /* 0x19a0 */
|
10, 60,143,119, 6,128,127,254, 15,116, 5, 44,232, 60, 1,119, /* 0x19a0 */
|
||||||
255,128, 63, 0,117,255,139, 7,102,193,232, 8,193,192, 16,134, /* 0x19b0 */
|
255,128, 63, 0,117,255,139, 7,102,193,232, 8,193,192, 16,134, /* 0x19b0 */
|
||||||
196, 41,248, 1,240,137, 7,131,199, 4,131,233, 4,138, 7,131, /* 0x19c0 */
|
196, 41,248, 1,232,137, 7,131,199, 4,131,233, 4,138, 7,131, /* 0x19c0 */
|
||||||
199, 1,226, 13,131,233, 1,127, 6,141,125,252, 49,192,138, 6, /* 0x19d0 */
|
199, 1,226, 13,131,233, 1,127, 6,141,125,252, 49,192,138, 6, /* 0x19d0 */
|
||||||
70, 9,192,116, 1, 60,239,119, 17, 1,199,139, 7,134,196,193, /* 0x19e0 */
|
70, 9,192,116, 1, 60,239,119, 17, 1,199,139, 7,134,196,193, /* 0x19e0 */
|
||||||
192, 16,134,196, 1,232,137, 7,235,226, 36, 15,193,224, 16,102, /* 0x19f0 */
|
192, 16,134,196, 1,232,137, 7,235,226, 36, 15,193,224, 16,102, /* 0x19f0 */
|
||||||
|
|||||||
@@ -29,11 +29,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_I386_LINUX_ELF_FOLD_SIZE 1691
|
#define STUB_I386_LINUX_ELF_FOLD_SIZE 1691
|
||||||
#define STUB_I386_LINUX_ELF_FOLD_ADLER32 0xe27fd53e
|
#define STUB_I386_LINUX_ELF_FOLD_ADLER32 0x5710d32e
|
||||||
#define STUB_I386_LINUX_ELF_FOLD_CRC32 0x75829ac3
|
#define STUB_I386_LINUX_ELF_FOLD_CRC32 0xcf21929e
|
||||||
|
|
||||||
unsigned char stub_i386_linux_elf_fold[1691] = {
|
unsigned char stub_i386_linux_elf_fold[1691] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
2, 0, 3, 0, 1, 0, 0, 0,128, 16,192, 0, 52, 0, 0, 0, /* 0x 10 */
|
2, 0, 3, 0, 1, 0, 0, 0,128, 16,192, 0, 52, 0, 0, 0, /* 0x 10 */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
||||||
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16,192, 0, /* 0x 30 */
|
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16,192, 0, /* 0x 30 */
|
||||||
|
|||||||
@@ -29,11 +29,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_SIZE 931
|
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_SIZE 931
|
||||||
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_ADLER32 0x488877dc
|
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_ADLER32 0xdce475cc
|
||||||
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_CRC32 0x399780ea
|
#define STUB_I386_LINUX_ELF_EXECVE_FOLD_CRC32 0x512b1d3a
|
||||||
|
|
||||||
unsigned char stub_i386_linux_elf_execve_fold[931] = {
|
unsigned char stub_i386_linux_elf_execve_fold[931] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */
|
2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
||||||
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16, 64, 0, /* 0x 30 */
|
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16, 64, 0, /* 0x 30 */
|
||||||
|
|||||||
@@ -29,11 +29,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_I386_LINUX_ELF_INTERP_FOLD_SIZE 1519
|
#define STUB_I386_LINUX_ELF_INTERP_FOLD_SIZE 1519
|
||||||
#define STUB_I386_LINUX_ELF_INTERP_FOLD_ADLER32 0xe82498de
|
#define STUB_I386_LINUX_ELF_INTERP_FOLD_ADLER32 0xbf8496ce
|
||||||
#define STUB_I386_LINUX_ELF_INTERP_FOLD_CRC32 0xd7e223de
|
#define STUB_I386_LINUX_ELF_INTERP_FOLD_CRC32 0xe6675cdc
|
||||||
|
|
||||||
unsigned char stub_i386_linux_elf_interp_fold[1519] = {
|
unsigned char stub_i386_linux_elf_interp_fold[1519] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
2, 0, 3, 0, 1, 0, 0, 0,116, 0, 1, 0, 52, 0, 0, 0, /* 0x 10 */
|
2, 0, 3, 0, 1, 0, 0, 0,116, 0, 1, 0, 52, 0, 0, 0, /* 0x 10 */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
||||||
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 0x 30 */
|
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 0x 30 */
|
||||||
|
|||||||
@@ -29,11 +29,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_I386_LINUX_ELF_SHELL_FOLD_SIZE 1194
|
#define STUB_I386_LINUX_ELF_SHELL_FOLD_SIZE 1194
|
||||||
#define STUB_I386_LINUX_ELF_SHELL_FOLD_ADLER32 0x63b3f90a
|
#define STUB_I386_LINUX_ELF_SHELL_FOLD_ADLER32 0xd981f6fa
|
||||||
#define STUB_I386_LINUX_ELF_SHELL_FOLD_CRC32 0xe2bc019d
|
#define STUB_I386_LINUX_ELF_SHELL_FOLD_CRC32 0x5d287cd0
|
||||||
|
|
||||||
unsigned char stub_i386_linux_elf_shell_fold[1194] = {
|
unsigned char stub_i386_linux_elf_shell_fold[1194] = {
|
||||||
127, 69, 76, 70, 1, 1, 1, 0, 76,105,110,117,120, 0, 0, 0, /* 0x 0 */
|
127, 69, 76, 70, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */
|
||||||
2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */
|
2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, /* 0x 10 */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 32, 0, 2, 0, 0, 0, /* 0x 20 */
|
||||||
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, /* 0x 30 */
|
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, /* 0x 30 */
|
||||||
|
|||||||
+1320
-1297
File diff suppressed because it is too large
Load Diff
@@ -67,7 +67,8 @@ def do_file(fn):
|
|||||||
elif opts.bfdname == "elf32-i386" and opts.elfosabi == "linux":
|
elif opts.bfdname == "elf32-i386" and opts.elfosabi == "linux":
|
||||||
if e_ident[4:7] != "\x01\x01\x01":
|
if e_ident[4:7] != "\x01\x01\x01":
|
||||||
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
||||||
write("\x00Linux\x00\x00\x00")
|
##write("\x00Linux\x00\x00\x00")
|
||||||
|
write("\x00" * 9)
|
||||||
elif opts.bfdname == "elf32-i386" and opts.elfosabi == "openbsd":
|
elif opts.bfdname == "elf32-i386" and opts.elfosabi == "openbsd":
|
||||||
if e_ident[4:7] != "\x01\x01\x01":
|
if e_ident[4:7] != "\x01\x01\x01":
|
||||||
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
||||||
@@ -75,11 +76,13 @@ def do_file(fn):
|
|||||||
elif opts.bfdname == "elf32-powerpc" and opts.elfosabi == "linux":
|
elif opts.bfdname == "elf32-powerpc" and opts.elfosabi == "linux":
|
||||||
if e_ident[4:7] != "\x01\x02\x01":
|
if e_ident[4:7] != "\x01\x02\x01":
|
||||||
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
||||||
write("\x00Linux\x00\x00\x00")
|
##write("\x00Linux\x00\x00\x00")
|
||||||
|
write("\x00" * 9)
|
||||||
elif opts.bfdname == "elf64-x86_64" and opts.elfosabi == "linux":
|
elif opts.bfdname == "elf64-x86_64" and opts.elfosabi == "linux":
|
||||||
if e_ident[4:7] != "\x02\x01\x01":
|
if e_ident[4:7] != "\x02\x01\x01":
|
||||||
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
raise Exception, "%s is not %s" % (fn, opts.bfdname)
|
||||||
write("\x00Linux\x00\x00\x00")
|
##write("\x00Linux\x00\x00\x00")
|
||||||
|
write("\x00" * 9)
|
||||||
else:
|
else:
|
||||||
done = 0
|
done = 0
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ def create_bindump(bindump_fn, dump_fn):
|
|||||||
e = f[1], int(f[2], 16), int(f[5], 16), int(f[6][3:], 10), len(sections)
|
e = f[1], int(f[2], 16), int(f[5], 16), int(f[6][3:], 10), len(sections)
|
||||||
sections.append(e)
|
sections.append(e)
|
||||||
assert not section_names.has_key(e[0]), e
|
assert not section_names.has_key(e[0]), e
|
||||||
|
assert not e[0].endswith(":"), ("bad section name", e)
|
||||||
section_names[e[0]] = e
|
section_names[e[0]] = e
|
||||||
##print sections
|
##print sections
|
||||||
# preprocessSymbols
|
# preprocessSymbols
|
||||||
@@ -100,6 +101,8 @@ def create_bindump(bindump_fn, dump_fn):
|
|||||||
assert f[1] in "gl", (l, f)
|
assert f[1] in "gl", (l, f)
|
||||||
assert f[2] in "dFO", (l, f)
|
assert f[2] in "dFO", (l, f)
|
||||||
section = section_names[f[3]]
|
section = section_names[f[3]]
|
||||||
|
elif len(f) == 5 and f[2] == "*ABS*":
|
||||||
|
pass
|
||||||
elif len(f) == 5:
|
elif len(f) == 5:
|
||||||
assert f[1] in "gl", (l, f)
|
assert f[1] in "gl", (l, f)
|
||||||
section = section_names[f[2]]
|
section = section_names[f[2]]
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro loadcon8 reg,val8
|
.macro loadcon8 reg,val8
|
||||||
.byte \val8, \reg<<4, 0xa0, 0xe3 /* mov \reg,#\val8 */
|
.long (0xe3<<24)|(0xa0<<16)|((\reg<<4)<<8)+(\val8) /* mov \reg,#\val8 */
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
// vi:ts=8:et:nowrap
|
// vi:ts=8:et:nowrap
|
||||||
|
|||||||
@@ -0,0 +1,291 @@
|
|||||||
|
#
|
||||||
|
# highly experimental support for i086 using Open Watcom C/C++
|
||||||
|
#
|
||||||
|
##export WATCOM ?= /opt/cc-i386-linux/watcom/open-watcom-1.6
|
||||||
|
#
|
||||||
|
|
||||||
|
MAKEFLAGS += -rR
|
||||||
|
.SUFFIXES:
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
|
||||||
|
ifndef top_srcdir
|
||||||
|
__dir_list = . .. ../.. ../../.. ../../../.. ../../../../..
|
||||||
|
__dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
||||||
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
|
STUBS =
|
||||||
|
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||||
|
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
|
||||||
|
STUBS += lzma_d_cf.S lzma_d_cs.S
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
default.targets = all
|
||||||
|
ifeq ($(strip $(STUBS)),)
|
||||||
|
STUBS = NO_STUBS
|
||||||
|
all.targets =
|
||||||
|
endif
|
||||||
|
include $(top_srcdir)/src/stub/Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# //
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
# enumerate the names of all environment variables
|
||||||
|
# FIXME: "origin" does not work for things like "export LC_ALL = C"
|
||||||
|
##__minienv_varlist = $(foreach v,$1,$(if $(findstring environment,$(origin $v)),$v))
|
||||||
|
__minienv_varlist = $(foreach v,$1,$(if $($v),$v))
|
||||||
|
# enumerate the names of all environment variables
|
||||||
|
__minienv_expand = $(foreach v,$(call __minienv_varlist,$1),$v='$($v)')
|
||||||
|
|
||||||
|
DOSBOX = true
|
||||||
|
DOSBOX = dosbox
|
||||||
|
DOSBOX = /usr/bin/time -p dosbox -exit
|
||||||
|
|
||||||
|
ifneq ($(wildcard /usr/bin/wine),)
|
||||||
|
WINEENV = @env
|
||||||
|
WINEENV = @env -i $(call __minienv_expand,DISPLAY HOME PATH USER TERM)
|
||||||
|
winedir_s = z:$(shell winepath -s $(realpath $1))
|
||||||
|
winedir_w = $(shell winepath -w $(realpath $1))
|
||||||
|
else
|
||||||
|
WINEENV = false 'WINEENV'
|
||||||
|
winedir_s = $1
|
||||||
|
winedir_w = $1
|
||||||
|
endif
|
||||||
|
|
||||||
|
# work around limitations of wine's cmd.exe
|
||||||
|
define mkbat
|
||||||
|
echo -E '@set PATH=$3;%PATH%' > $1
|
||||||
|
echo -E '@set INCLUDE=$4' >> $1
|
||||||
|
echo -E '@set LIB=$5' >> $1
|
||||||
|
echo -E '@set a=%1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
|
||||||
|
echo -e '@shift\n@shift\n@shift\n@shift\n@shift' >> $1
|
||||||
|
echo -e '@shift\n@shift\n@shift\n@shift' >> $1
|
||||||
|
echo -E '@set b=%1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
|
||||||
|
echo -e '@shift\n@shift\n@shift\n@shift\n@shift' >> $1
|
||||||
|
echo -e '@shift\n@shift\n@shift\n@shift' >> $1
|
||||||
|
echo -E '$2 %a% %b% %1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
|
||||||
|
$(UNIX2DOS) $1
|
||||||
|
endef
|
||||||
|
|
||||||
|
TMP_DEPS = tmp/.tmp-stamp tmp/bcc.bat tmp/cl.bat tmp/dmc.bat
|
||||||
|
|
||||||
|
tmp/bcc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
|
||||||
|
@$(call mkbat,$@,bcc.exe,$(call winedir_w,$(BC502DIR)/bin))
|
||||||
|
tmp/cl.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
|
||||||
|
@$(call mkbat,$@,cl.exe,$(call winedir_w,$(VC152DIR)/bin),$(call winedir_w,$(VC152DIR)/include),$(call winedir_w,$(VC152DIR)/lib))
|
||||||
|
tmp/dmc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
|
||||||
|
@$(call mkbat,$@,dmc.exe,$(call winedir_w,$(DM849DIR)/bin))
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // method-lzma
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
lzma_d_c% : tc_list = method-lzma arch-i086 default
|
||||||
|
lzma_d_c% : tc_bfdname =
|
||||||
|
|
||||||
|
# gcc
|
||||||
|
c := tc.arch-i086.gcc
|
||||||
|
$c += -MF /dev/null
|
||||||
|
$c += -Wall -W
|
||||||
|
$c += -I$(UPX_LZMADIR)
|
||||||
|
$c += -I$(top_srcdir)/src
|
||||||
|
|
||||||
|
# Borland C/C++ 5.02
|
||||||
|
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
|
||||||
|
c := tc.method-lzma.bcc
|
||||||
|
$c = $(WINEENV) wine cmd.exe /c tmp/bcc.bat
|
||||||
|
$c += -ms
|
||||||
|
$c += -O1 -1
|
||||||
|
$c += -w
|
||||||
|
$c += -D__INT_MAX__=32767
|
||||||
|
$c += -I$(subst \,/,$(call winedir_w,$(UPX_LZMADIR)/C/7zip/Compress/LZMA_C))
|
||||||
|
$c += -I$(top_srcdir)/src
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Digital Mars C/C++ 8.49
|
||||||
|
# http://www.digitalmars.com/download/freecompiler.html
|
||||||
|
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
|
||||||
|
c := tc.method-lzma.dmc
|
||||||
|
$c = $(WINEENV) CFLAGS='$(DMC)' wine cmd.exe /c tmp/dmc.bat
|
||||||
|
$c += -ms -R
|
||||||
|
$c += -NS
|
||||||
|
$c += -w- -w7 -r
|
||||||
|
DMC := -o -0
|
||||||
|
DMC += -D__INT_MAX__=32767
|
||||||
|
DMC += -I$(call winedir_w,$(UPX_LZMADIR))
|
||||||
|
DMC += -I$(call winedir_w,$(top_srcdir)/src)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Visual C/C++ 1.52 (8.00c)
|
||||||
|
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
|
||||||
|
c := tc.method-lzma.cl
|
||||||
|
$c = $(WINEENV) CL='$(CL)' wine cmd.exe /c tmp/cl.bat
|
||||||
|
$c += -AS -Gd
|
||||||
|
$c += -Gy
|
||||||
|
$c += -O2 -Gf -Gs -G0
|
||||||
|
$c += -W4
|
||||||
|
CL := -nologo
|
||||||
|
CL += -D__INT_MAX__=32767
|
||||||
|
CL += -I$(call winedir_s,$(UPX_LZMADIR))
|
||||||
|
CL += -I$(call winedir_s,$(top_srcdir)/src)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Open Watcom C/C++ 1.6
|
||||||
|
# http://www.openwatcom.com/
|
||||||
|
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
|
||||||
|
c := tc.method-lzma.wcl
|
||||||
|
$c = PATH='$(WATCOM)/binl:$(PATH)' $(WATCOM)/binl/wcl -zq -bt=dos
|
||||||
|
$c += -ms -ecc
|
||||||
|
$c += -zm -zc
|
||||||
|
$c += -os -s -0 -d0
|
||||||
|
$c += -w5 -we -fr=/dev/null
|
||||||
|
$c += -D__INT_MAX__=32767
|
||||||
|
$c += -I$(UPX_LZMADIR)
|
||||||
|
$c += -I$(top_srcdir)/src
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||||
|
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
|
||||||
|
|
||||||
|
lzma_d_c%.S : tmp/lzma_d_c%.i cleanasm.py $(MAKEFILE_LIST)
|
||||||
|
$(PYTHON) cleanasm.py --label-prefix=$(LABEL_PREFIX) $< $@
|
||||||
|
|
||||||
|
tmp/lzma_d_c%.i : lzma_d_c.c wdis2gas.py $(MAKEFILE_LIST) $(TMP_DEPS)
|
||||||
|
rm -f tmp/$T*.i tmp/$T*.o tmp/$T*.obj tmp/$T*.S
|
||||||
|
# compile
|
||||||
|
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
|
||||||
|
## $(call tc,bcc) $(PP_FLAGS) -c -otmp/$T_bc.obj $<
|
||||||
|
## $(call tc,wdis) tmp/$T_bc.obj | $(RTRIM) > tmp/$T_bc.obj.disasm
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
|
||||||
|
$(call tc,dmc) $(PP_FLAGS) -c -otmp/$T_dm.obj $<
|
||||||
|
$(call tc,wdis) tmp/$T_dm.obj | $(RTRIM) > tmp/$T_dm.obj.disasm
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
|
||||||
|
$(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T_vc.obj $<
|
||||||
|
$(call tc,wdis) tmp/$T_vc.obj | $(RTRIM) > tmp/$T_vc.obj.disasm
|
||||||
|
endif
|
||||||
|
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
|
||||||
|
$(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T_wc.obj $<
|
||||||
|
$(call tc,wdis) tmp/$T_wc.obj | $(RTRIM) > tmp/$T_wc.obj.disasm
|
||||||
|
endif
|
||||||
|
# convert
|
||||||
|
$(PYTHON) wdis2gas.py tmp/$T_wc.obj.disasm tmp/$T.S
|
||||||
|
$(call tc,gcc) -c -o tmp/$T.o tmp/$T.S
|
||||||
|
$(call tc,f-objstrip,tmp/$T.o)
|
||||||
|
$(call tc,objdump) -b elf32-i386 -m i8086 -M intel -dr -j .text.LzmaDecode --no-show -w tmp/$T.o | $(RTRIM) | perl -pe 's/DWORD/dword/g; s/WORD/word/g; s/BYTE/byte/g; s/PTR/ptr/g;' > $@
|
||||||
|
|
||||||
|
.PRECIOUS: lzma_d_c%.i tmp/lzma_d_c%.i
|
||||||
|
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
lzma_d_cf.% : PP_FLAGS = -DFAST
|
||||||
|
lzma_d_cs.% : PP_FLAGS = -DSMALL
|
||||||
|
lzma_d_cf.% : LABEL_PREFIX = .Lf
|
||||||
|
lzma_d_cs.% : LABEL_PREFIX = .Ls
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // cc_test
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(WATCOM)/binl/wdis),)
|
||||||
|
|
||||||
|
CC_TEST_DEPS = $(MAKEFILE_LIST) $(TMP_DEPS)
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
|
||||||
|
cc_test_bc : tc_list = method-lzma arch-i086 default
|
||||||
|
cc_test_bc: cc_test.c $(CC_TEST_DEPS)
|
||||||
|
$(call tc,bcc) $(PP_FLAGS) -c -otmp/$T.obj $<
|
||||||
|
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
|
||||||
|
cc_test_all: cc_test_bc
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
|
||||||
|
cc_test_dm : tc_list = method-lzma arch-i086 default
|
||||||
|
cc_test_dm: cc_test.c $(CC_TEST_DEPS)
|
||||||
|
$(call tc,dmc) $(PP_FLAGS) -c -otmp/$T.obj $<
|
||||||
|
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
|
||||||
|
cc_test_all: cc_test_dm
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
|
||||||
|
cc_test_vc : tc_list = method-lzma arch-i086 default
|
||||||
|
cc_test_vc: cc_test.c $(CC_TEST_DEPS)
|
||||||
|
$(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T.obj $<
|
||||||
|
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
|
||||||
|
cc_test_all: cc_test_vc
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
|
||||||
|
cc_test_wc : tc_list = method-lzma arch-i086 default
|
||||||
|
cc_test_wc: cc_test.c $(CC_TEST_DEPS)
|
||||||
|
$(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T.obj $<
|
||||||
|
$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
|
||||||
|
cc_test_all: cc_test_wc
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: cc_test_all
|
||||||
|
|
||||||
|
endif # wdis
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // l_test
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
L_TEST_DEPS = lzma_d_c.c $(MAKEFILE_LIST) $(TMP_DEPS)
|
||||||
|
|
||||||
|
tmp/l_test_gcc_i386.% : tc_list = arch-i086 default
|
||||||
|
tmp/l_test_gcc_i386.out: l_test.c $(L_TEST_DEPS)
|
||||||
|
$(call tc,gcc) -O0 -g -o $@ $<
|
||||||
|
./$@
|
||||||
|
l_test_all: tmp/l_test_gcc_i386.out
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
|
||||||
|
tmp/l_test_bc.% : tc_list = method-lzma arch-i086 default
|
||||||
|
tmp/l_test_bc.exe: l_test.c $(L_TEST_DEPS)
|
||||||
|
$(call tc,bcc) -o$(subst /,\\,$@) $<
|
||||||
|
@rm -f l_test.o l_test.obj
|
||||||
|
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
|
||||||
|
##l_test_all: tmp/l_test_bc.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
|
||||||
|
tmp/l_test_dm.% : tc_list = method-lzma arch-i086 default
|
||||||
|
tmp/l_test_dm.exe: l_test.c $(L_TEST_DEPS)
|
||||||
|
$(call tc,dmc) -ml -o$(subst /,\\,$@) $<
|
||||||
|
@rm -f l_test.o l_test.obj
|
||||||
|
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
|
||||||
|
l_test_all: tmp/l_test_dm.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
|
||||||
|
tmp/l_test_vc.% : tc_list = method-lzma arch-i086 default
|
||||||
|
tmp/l_test_vc.exe: l_test.c $(L_TEST_DEPS)
|
||||||
|
$(call tc,cl) -Fe$(subst /,\\,$@) $<
|
||||||
|
@rm -f l_test.o l_test.obj
|
||||||
|
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
|
||||||
|
l_test_all: tmp/l_test_vc.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
|
||||||
|
tmp/l_test_wc.% : tc_list = method-lzma arch-i086 default
|
||||||
|
tmp/l_test_wc.exe: l_test.c $(L_TEST_DEPS)
|
||||||
|
$(call tc,wcl) -fe=$@ $<
|
||||||
|
@rm -f l_test.o l_test.obj
|
||||||
|
cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
|
||||||
|
l_test_all: tmp/l_test_wc.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: l_test_all
|
||||||
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/* cc_test.c -- examine compiler-generated library calls
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 2006-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<mfx@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 && defined(__WATCOMC__)
|
||||||
|
#define __cdecl __watcall
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef long int32_t;
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// simulated 32-bit pointer
|
||||||
|
typedef char __huge* hptr;
|
||||||
|
typedef long hptrdiff_t;
|
||||||
|
typedef unsigned long hsize_t;
|
||||||
|
#elif 1
|
||||||
|
// ignore segment overflow
|
||||||
|
typedef char __far* hptr;
|
||||||
|
typedef long hptrdiff_t;
|
||||||
|
typedef unsigned long hsize_t;
|
||||||
|
#else
|
||||||
|
// no segment
|
||||||
|
typedef char __near* hptr;
|
||||||
|
typedef short hptrdiff_t;
|
||||||
|
typedef unsigned short hsize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// pia - pointer add
|
||||||
|
hptr __cdecl pia(hptr a, hsize_t d) { return a + d; }
|
||||||
|
hptr __cdecl pia1(hptr a) { return a + 1; }
|
||||||
|
|
||||||
|
// pis - pointer subtract
|
||||||
|
hptr __cdecl pis(hptr a, hsize_t d) { return a - d; }
|
||||||
|
hptr __cdecl pis1(hptr a) { return a - 1; }
|
||||||
|
|
||||||
|
// pts - pointer diff
|
||||||
|
hptrdiff_t __cdecl pts(hptr a, hptr b) { return a - b; }
|
||||||
|
|
||||||
|
// ptc - pointer compare (__PTC sets zero and carry flags)
|
||||||
|
int __cdecl ptc_eq(hptr a, hptr b) { return a == b; }
|
||||||
|
int __cdecl ptc_ne(hptr a, hptr b) { return a != b; }
|
||||||
|
int __cdecl ptc_lt(hptr a, hptr b) { return a < b; }
|
||||||
|
int __cdecl ptc_le(hptr a, hptr b) { return a <= b; }
|
||||||
|
int __cdecl ptc_gt(hptr a, hptr b) { return a > b; }
|
||||||
|
int __cdecl ptc_ge(hptr a, hptr b) { return a >= b; }
|
||||||
|
|
||||||
|
// u4m - unsigned multiplication
|
||||||
|
uint32_t __cdecl u4m(uint32_t a, uint32_t b) { return a * b; }
|
||||||
|
uint32_t __pascal u4m_p(uint32_t a, uint32_t b) { return b * a; }
|
||||||
|
|
||||||
|
// i4m - signed multiplication
|
||||||
|
int32_t __cdecl i4m(int32_t a, int32_t b) { return a * b; }
|
||||||
|
int32_t __pascal i4m_p(int32_t a, int32_t b) { return b * a; }
|
||||||
|
|
||||||
|
// just for testing
|
||||||
|
uint16_t __cdecl u2m(uint16_t a, uint16_t b) { return a * b; }
|
||||||
|
int16_t __cdecl i2m(int16_t a, int16_t b) { return a * b; }
|
||||||
|
uint32_t __cdecl u2m4(uint16_t a, uint16_t b) { return a * b; }
|
||||||
|
int32_t __cdecl i2m4(int16_t a, int16_t b) { return a * b; }
|
||||||
|
|
||||||
|
uint16_t __cdecl u2shl8 (uint16_t a) { return a << 8; }
|
||||||
|
uint32_t __cdecl u4shl8 (uint32_t a) { return a << 8; }
|
||||||
|
uint16_t __cdecl u2shl12(uint16_t a) { return a << 12; }
|
||||||
|
uint32_t __cdecl u4shl12(uint32_t a) { return a << 12; }
|
||||||
|
uint32_t __cdecl u4shl16(uint32_t a) { return a << 16; }
|
||||||
|
uint32_t __cdecl u4shl24(uint32_t a) { return a << 24; }
|
||||||
|
uint16_t __cdecl u2shlv(uint16_t a, unsigned v) { return a << v; }
|
||||||
|
uint32_t __cdecl u4shlv(uint32_t a, unsigned v) { return a << v; }
|
||||||
|
|
||||||
|
void __pascal p4nshlv_v(unsigned char v, uint32_t __near *a) { *a <<= v; }
|
||||||
|
void __pascal p4fshlv_v(unsigned char v, uint32_t __far *a) { *a <<= v; }
|
||||||
|
uint32_t __pascal p4nshlv(unsigned char v, uint32_t __near *a) { return *a <<= v; }
|
||||||
|
uint32_t __pascal p4fshlv(unsigned char v, uint32_t __far *a) { return *a <<= v; }
|
||||||
|
|
||||||
|
hptrdiff_t __cdecl hptr2int(hptr a) { return (hptrdiff_t) a; }
|
||||||
|
hptr __cdecl int2hptr(hptrdiff_t a) { return (hptr) a; }
|
||||||
|
|
||||||
|
|
||||||
|
/* vim:set ts=4 et: */
|
||||||
@@ -0,0 +1,409 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# cleanasm.py --
|
||||||
|
#
|
||||||
|
# This file is part of the UPX executable compressor.
|
||||||
|
#
|
||||||
|
# Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# UPX and the UCL library are free software; you can redistribute them
|
||||||
|
# and/or modify them under the terms of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation; either version 2 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; see the file COPYING.
|
||||||
|
# If not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
# <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
import getopt, os, re, string, sys
|
||||||
|
|
||||||
|
|
||||||
|
class opts:
|
||||||
|
label_prefix = ".L"
|
||||||
|
verbose = 0
|
||||||
|
# optimizer flags
|
||||||
|
auto_inline = 1
|
||||||
|
call_rewrite = 1
|
||||||
|
loop_rewrite = 1
|
||||||
|
|
||||||
|
|
||||||
|
inline_map = {
|
||||||
|
"__aNNalshl": ["M_aNNalshl", 1],
|
||||||
|
"__aNahdiff": ["M_aNahdiff", 1],
|
||||||
|
"__PIA": ["M_PIA", 999],
|
||||||
|
"__PTS": ["M_PTS", 999],
|
||||||
|
"__PTC": ["M_PTC", 999],
|
||||||
|
"__U4M": ["M_U4M", 999],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // main
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
shortopts, longopts = "qv", [
|
||||||
|
"label-prefix=", "quiet", "verbose"
|
||||||
|
]
|
||||||
|
xopts, args = getopt.gnu_getopt(argv[1:], shortopts, longopts)
|
||||||
|
for opt, optarg in xopts:
|
||||||
|
if 0: pass
|
||||||
|
elif opt in ["-q", "--quiet"]: opts.verbose = opts.verbose - 1
|
||||||
|
elif opt in ["-v", "--verbose"]: opts.verbose = opts.verbose + 1
|
||||||
|
elif opt in ["--label-prefix"]: opts.label_prefix = optarg
|
||||||
|
else: assert 0, ("getopt problem:", opt, optarg, xopts, args)
|
||||||
|
|
||||||
|
#
|
||||||
|
assert opts.label_prefix
|
||||||
|
assert len(args) == 2
|
||||||
|
ifile = args[0]
|
||||||
|
ofile = args[1]
|
||||||
|
# read ifile
|
||||||
|
lines = open(ifile, "rb").readlines()
|
||||||
|
lines = filter(None, map(string.rstrip, lines))
|
||||||
|
#
|
||||||
|
#
|
||||||
|
labels = {}
|
||||||
|
def parse_label(inst, args):
|
||||||
|
k = v = None
|
||||||
|
m = re.search(r"^(.*?)\b(2|R_386_PC16)\s+(__\w+)$", args)
|
||||||
|
if m and k is None:
|
||||||
|
# external 2-byte label
|
||||||
|
k, v = m.group(3).strip(), [1, 2, None, 0]
|
||||||
|
m = re.search("^0x([0-9a-z]+)$", args)
|
||||||
|
if m and k is None:
|
||||||
|
# local label
|
||||||
|
k, v = m.group(1).strip(), [0, 0, None, 0]
|
||||||
|
m = re.search("^([0-9a-z]+)\s+<", args)
|
||||||
|
if m and k is None:
|
||||||
|
# local label
|
||||||
|
k, v = m.group(1).strip(), [0, 0, None, 0]
|
||||||
|
assert k and v, (inst, args)
|
||||||
|
v[2] = k # new name
|
||||||
|
if labels.has_key(k):
|
||||||
|
assert labels[k][:2] == v[:2]
|
||||||
|
return k, v
|
||||||
|
def add_label(k, v):
|
||||||
|
if labels.has_key(k):
|
||||||
|
assert labels[k][:2] == v[:2]
|
||||||
|
else:
|
||||||
|
labels[k] = v
|
||||||
|
labels[k][3] += 1 # usage counter
|
||||||
|
return k
|
||||||
|
|
||||||
|
olines = []
|
||||||
|
def omatch(pos, mlen, m, debug=0):
|
||||||
|
assert len(m) >= abs(mlen)
|
||||||
|
def sgn(x):
|
||||||
|
if x < 0: return -1
|
||||||
|
if x > 0: return 1
|
||||||
|
return 0
|
||||||
|
def match(a, b):
|
||||||
|
if b is None:
|
||||||
|
return False
|
||||||
|
if "^" in a or "*" in a:
|
||||||
|
# regexp
|
||||||
|
return re.search(a, b.lower())
|
||||||
|
else:
|
||||||
|
return a.lower() == b.lower()
|
||||||
|
mpos = []
|
||||||
|
while len(mpos) != abs(mlen):
|
||||||
|
if pos < 0 or pos >= len(olines):
|
||||||
|
return []
|
||||||
|
o = olines[pos]
|
||||||
|
if o[1] != "*DEL*":
|
||||||
|
mpos.append(pos)
|
||||||
|
pos += sgn(mlen)
|
||||||
|
if mlen < 0:
|
||||||
|
mpos.reverse()
|
||||||
|
if debug and 1: print mlen, m, [olines[x] for x in mpos]
|
||||||
|
dpos = []
|
||||||
|
i = -abs(mlen)
|
||||||
|
while i < 0:
|
||||||
|
pos = mpos[i]
|
||||||
|
o = olines[pos]
|
||||||
|
assert o[1] != "*DEL*"
|
||||||
|
assert len(m[i]) == 2, (i, m)
|
||||||
|
m0 = match(m[i][0], o[1])
|
||||||
|
m1 = match(m[i][1], o[2])
|
||||||
|
if not m0 or not m1:
|
||||||
|
return []
|
||||||
|
dpos.append([pos, m0, m1])
|
||||||
|
i += 1
|
||||||
|
assert len(dpos) == abs(mlen)
|
||||||
|
return dpos
|
||||||
|
def orewrite_inst(i, inst, args, dpos):
|
||||||
|
for pos, m0, m1 in dpos:
|
||||||
|
olines[pos][1] = "*DEL*"
|
||||||
|
olines[i][1] = inst
|
||||||
|
olines[i][2] = args
|
||||||
|
olines[i][3] = None
|
||||||
|
def orewrite_call(i, k, v, dpos):
|
||||||
|
for pos, m0, m1 in dpos:
|
||||||
|
olines[pos][1] = "*DEL*"
|
||||||
|
v[2] = k
|
||||||
|
olines[i][2] = None
|
||||||
|
olines[i][3] = add_label(k, v)
|
||||||
|
|
||||||
|
#
|
||||||
|
# pass 1
|
||||||
|
func = None
|
||||||
|
for i in range(len(lines)):
|
||||||
|
l = lines[i]
|
||||||
|
m = re.search(r"^0{8,16}\s*<(\.text\.)?(\w+)>:", l)
|
||||||
|
if m:
|
||||||
|
func = re.sub(r"^_+|_+$", "", m.group(2))
|
||||||
|
if not func in ["LzmaDecode"]:
|
||||||
|
continue
|
||||||
|
m = re.search(r"^(\s*[0-9a-z]+):\s+(\w+)(.*)", l)
|
||||||
|
if not m:
|
||||||
|
continue
|
||||||
|
label = m.group(1).strip()
|
||||||
|
inst = m.group(2).strip()
|
||||||
|
args = ""
|
||||||
|
if m.group(3): args = m.group(3).strip()
|
||||||
|
#
|
||||||
|
if inst in ["movl",] and re.search(r"\b[de]s\b", args):
|
||||||
|
# fix bug in objdump
|
||||||
|
inst = "movw"
|
||||||
|
m = re.search(r"^(.+?)\b0x0\s+(\w+):\s+(1|2|R_386_16|R_386_PC16)\s+(__\w+)$", args)
|
||||||
|
if m:
|
||||||
|
# 1 or 2 byte reloc
|
||||||
|
args = m.group(1) + m.group(4)
|
||||||
|
olines.append([label, inst, args, None])
|
||||||
|
#
|
||||||
|
# pass 2
|
||||||
|
for i in range(len(olines)):
|
||||||
|
label, inst, args, args_label = olines[i]
|
||||||
|
#
|
||||||
|
if inst == "*DEL*":
|
||||||
|
continue
|
||||||
|
#
|
||||||
|
if opts.call_rewrite and inst in ["call"]:
|
||||||
|
k, v = parse_label(inst, args)
|
||||||
|
if v[:2] == [1, 2]: # external 2-byte
|
||||||
|
if k == "__aNahdiff":
|
||||||
|
s = [
|
||||||
|
["push", "word ptr [bp+8]"],
|
||||||
|
["push", "word ptr [bp+6]"],
|
||||||
|
["push", r"word ptr \[bp([+-]\d+)\]$"],
|
||||||
|
["push", r"word ptr \[bp([+-]\d+)\]$"],
|
||||||
|
]
|
||||||
|
dpos = omatch(i-1, -4, s)
|
||||||
|
if dpos:
|
||||||
|
orewrite_inst(i, "*DEL*", "", dpos)
|
||||||
|
continue
|
||||||
|
if k in ["__LMUL", "__U4M",]:
|
||||||
|
s1 = [
|
||||||
|
["mov", "bx,0x300"],
|
||||||
|
["xor", "cx,cx"],
|
||||||
|
]
|
||||||
|
s2 = [
|
||||||
|
["shl", "ax,1"],
|
||||||
|
["rcl", "dx,1"],
|
||||||
|
]
|
||||||
|
dpos1 = omatch(i-1, -2, s1)
|
||||||
|
dpos2 = omatch(i+1, 2, s2)
|
||||||
|
if dpos1 and dpos2:
|
||||||
|
orewrite_inst(i, "M_U4M_dxax_0x0600", "", dpos1 + dpos2)
|
||||||
|
continue
|
||||||
|
s = [
|
||||||
|
["mov", "bx,word ptr [bx]"],
|
||||||
|
["xor", "cx,cx"],
|
||||||
|
]
|
||||||
|
dpos = omatch(i-1, -2, s, debug=0)
|
||||||
|
if 0 and dpos:
|
||||||
|
orewrite_inst(i, "M_U4M_dxax_00bx_ptr", "", dpos)
|
||||||
|
continue
|
||||||
|
dpos = omatch(i-1, -1, s)
|
||||||
|
if dpos:
|
||||||
|
orewrite_inst(i, "M_U4M_dxax_00bx", "", dpos)
|
||||||
|
continue
|
||||||
|
if k == "__PIA":
|
||||||
|
s = [
|
||||||
|
["mov", "bx,0x1"],
|
||||||
|
["xor", "cx,cx"],
|
||||||
|
]
|
||||||
|
dpos = omatch(i-1, -2, s)
|
||||||
|
if dpos:
|
||||||
|
orewrite_inst(i, "M_PIA1", "", dpos)
|
||||||
|
continue
|
||||||
|
if k == "__PTC":
|
||||||
|
s = [
|
||||||
|
["jne", "(.*)"],
|
||||||
|
]
|
||||||
|
dpos = omatch(i+1, 1, s)
|
||||||
|
if dpos:
|
||||||
|
olines[i][1] = "M_PTC_JNE"
|
||||||
|
k, v = parse_label("jne", dpos[0][2].group(1))
|
||||||
|
orewrite_call(i, k, v, dpos)
|
||||||
|
continue
|
||||||
|
if opts.loop_rewrite and inst in ["loop"]:
|
||||||
|
s = [
|
||||||
|
["mov", r"^c[lx],0xb$"],
|
||||||
|
["shr", "dx,1"],
|
||||||
|
["rcr", "ax,1"],
|
||||||
|
]
|
||||||
|
dpos = omatch(i-1, -3, s)
|
||||||
|
if dpos:
|
||||||
|
orewrite_inst(i, "M_shrd_11", "", dpos)
|
||||||
|
continue
|
||||||
|
s = [
|
||||||
|
["mov", r"^c[lx],0x8$"],
|
||||||
|
["shl", "ax,1"],
|
||||||
|
["rcl", "dx,1"],
|
||||||
|
]
|
||||||
|
dpos = omatch(i-1, -3, s)
|
||||||
|
if dpos:
|
||||||
|
orewrite_inst(i, "M_shld_8", "", dpos)
|
||||||
|
continue
|
||||||
|
s1 = [
|
||||||
|
["mov", r"^c[lx],0x8$"],
|
||||||
|
["shl", "si,1"],
|
||||||
|
["rcl", "di,1"],
|
||||||
|
]
|
||||||
|
s2 = [
|
||||||
|
["les", r"^bx,dword ptr \[bp([+-]\d+)\]$"],
|
||||||
|
]
|
||||||
|
dpos1 = omatch(i-1, -3, s1)
|
||||||
|
dpos2 = omatch(i+1, 1, s2)
|
||||||
|
if 1 and dpos1 and dpos2:
|
||||||
|
# bx and cx are free for use
|
||||||
|
orewrite_inst(i, "M_shld_disi_8_bxcx", "", dpos1)
|
||||||
|
continue
|
||||||
|
s1 = [
|
||||||
|
["mov", "ax,si"],
|
||||||
|
["mov", r"^c[lx],0x8$"],
|
||||||
|
["shl", "ax,1"],
|
||||||
|
["rcl", "di,1"],
|
||||||
|
]
|
||||||
|
s2 = [
|
||||||
|
["mov", "si,ax"],
|
||||||
|
["les", r"^bx,dword ptr \[bp([+-]\d+)\]$"],
|
||||||
|
]
|
||||||
|
dpos1 = omatch(i-1, -4, s1)
|
||||||
|
dpos2 = omatch(i+1, 2, s2)
|
||||||
|
if 1 and dpos1 and dpos2:
|
||||||
|
# bx and cx are free for use
|
||||||
|
orewrite_inst(i, "M_shld_diax_8_bxcx", "", dpos1[-3:])
|
||||||
|
continue
|
||||||
|
s1 = [
|
||||||
|
["mov", r"^c[lx],0x8$"],
|
||||||
|
["shl", r"^word ptr \[bp([+-]\d+)\],1$"],
|
||||||
|
["rcl", r"^word ptr \[bp([+-]\d+)\],1$"],
|
||||||
|
]
|
||||||
|
s2 = [
|
||||||
|
["mov", r"^dx,word ptr"],
|
||||||
|
["mov", r"^ax,word ptr"],
|
||||||
|
]
|
||||||
|
s3 = [
|
||||||
|
["mov", r"^ax,word ptr"],
|
||||||
|
["mov", r"^dx,word ptr"],
|
||||||
|
]
|
||||||
|
dpos1 = omatch(i-1, -3, s1)
|
||||||
|
dpos2 = omatch(i+1, 2, s2)
|
||||||
|
dpos3 = omatch(i+1, 2, s3)
|
||||||
|
if dpos1 and (dpos2 or dos3):
|
||||||
|
bp_dx, bp_ax = dpos1[-1][2].group(1), dpos1[-2][2].group(1)
|
||||||
|
m = "M_shld_8_bp %s %s" % (bp_dx, bp_ax)
|
||||||
|
orewrite_inst(i, m, "", dpos1)
|
||||||
|
continue
|
||||||
|
s1 = [
|
||||||
|
["mov", r"^word ptr \[bp([+-]\d+)\],si$"],
|
||||||
|
["mov", r"^word ptr \[bp([+-]\d+)\],di$"],
|
||||||
|
["mov", r"^c[lx],0xb$"],
|
||||||
|
["shr", r"^word ptr \[bp([+-]\d+)\],1$"],
|
||||||
|
["rcr", r"^word ptr \[bp([+-]\d+)\],1$"],
|
||||||
|
]
|
||||||
|
s2 = [
|
||||||
|
["mov", r"^bx,word ptr"],
|
||||||
|
["mov", r"^bx,word ptr"],
|
||||||
|
["mov", r"^ax,word ptr \[bp([+-]\d+)\]$"],
|
||||||
|
["mov", r"^dx,word ptr \[bp([+-]\d+)\]$"],
|
||||||
|
]
|
||||||
|
dpos1 = omatch(i-1, -5, s1)
|
||||||
|
dpos2 = omatch(i+1, 4, s2)
|
||||||
|
if dpos1 and dpos2:
|
||||||
|
bp_dx, bp_ax = dpos1[-2][2].group(1), dpos1[-1][2].group(1)
|
||||||
|
bp_di, bp_si = dpos1[-4][2].group(1), dpos1[-5][2].group(1)
|
||||||
|
assert bp_dx == dpos2[-1][2].group(1)
|
||||||
|
assert bp_ax == dpos2[-2][2].group(1)
|
||||||
|
assert bp_dx == bp_di
|
||||||
|
assert bp_ax == bp_si
|
||||||
|
m = "M_shrd_11_disi_bp %s %s" % (bp_dx, bp_ax)
|
||||||
|
orewrite_inst(i, m, "", dpos1 + dpos2[-2:])
|
||||||
|
continue
|
||||||
|
#
|
||||||
|
if inst in [
|
||||||
|
"call", "ja", "jae", "jb", "jbe", "jcxz", "je",
|
||||||
|
"jg", "jge", "jl", "jle", "jmp", "jne", "loop",
|
||||||
|
]:
|
||||||
|
k, v = parse_label(inst, args)
|
||||||
|
olines[i][2] = None
|
||||||
|
olines[i][3] = add_label(k, v)
|
||||||
|
#
|
||||||
|
# pass 3
|
||||||
|
digits, i = 1, len(labels)
|
||||||
|
while i >= 10:
|
||||||
|
digits += 1
|
||||||
|
i /= 10
|
||||||
|
format = "%s0%dd" % ("%", digits)
|
||||||
|
counter = 0
|
||||||
|
for i in range(len(olines)):
|
||||||
|
label, inst, args, args_label = olines[i]
|
||||||
|
# rewrite local labels
|
||||||
|
v = labels.get(label)
|
||||||
|
if v is not None:
|
||||||
|
assert v[:3] == [0, 0, label], (label, v)
|
||||||
|
v[2] = opts.label_prefix + format % counter
|
||||||
|
counter += 1
|
||||||
|
# handle inlining
|
||||||
|
if opts.auto_inline and inst == "call":
|
||||||
|
v = labels[args_label]
|
||||||
|
if v[:2] == [1, 2]: # external 2-byte
|
||||||
|
x = inline_map.get(v[2])
|
||||||
|
if x and v[3] <= x[1]: # max. number of calls
|
||||||
|
##print "inline", v, x
|
||||||
|
if x:
|
||||||
|
olines[i][1] = x[0]
|
||||||
|
olines[i][2] = "/* inlined */"
|
||||||
|
olines[i][2] = ""
|
||||||
|
olines[i][3] = None
|
||||||
|
#
|
||||||
|
# write ofile
|
||||||
|
ofp = open(ofile, "wb")
|
||||||
|
for label, inst, args, args_label in olines:
|
||||||
|
if labels.has_key(label):
|
||||||
|
if opts.verbose:
|
||||||
|
ofp.write("%s: /* %d */\n" % (labels[label][2], labels[label][3]))
|
||||||
|
else:
|
||||||
|
ofp.write("%s:\n" % (labels[label][2]))
|
||||||
|
if inst == "*DEL*":
|
||||||
|
continue
|
||||||
|
if args_label:
|
||||||
|
if opts.verbose:
|
||||||
|
args = "%s /* %d */" % (labels[args_label][2], labels[args_label][3])
|
||||||
|
else:
|
||||||
|
args = labels[args_label][2]
|
||||||
|
l = "%8s%-7s %s" % ("", inst, args)
|
||||||
|
ofp.write(l.rstrip() + "\n")
|
||||||
|
ofp.close()
|
||||||
|
##print olines
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main(sys.argv))
|
||||||
|
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/* l_test.c --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<mfx@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "stub/src/c/lzma_d_c.c"
|
||||||
|
|
||||||
|
#if (ACC_ARCH_I086)
|
||||||
|
#define bytep unsigned char __huge *
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
#else
|
||||||
|
#define bytep unsigned char *
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (ACC_OS_DOS16)
|
||||||
|
# if (ACC_CC_BORLANDC || ACC_CC_TURBOC)
|
||||||
|
int __cdecl printf(const char *, ...);
|
||||||
|
void * __cdecl malloc(unsigned);
|
||||||
|
void __far * __cdecl farmalloc(unsigned long);
|
||||||
|
# define acc_halloc(x) ((void __huge *) farmalloc(x))
|
||||||
|
# elif (ACC_CC_DMC || ACC_CC_MSC)
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <malloc.h>
|
||||||
|
# define acc_halloc(x) _halloc(x,1)
|
||||||
|
# elif (ACC_CC_WATCOMC)
|
||||||
|
int __watcall printf(const char *, ...);
|
||||||
|
void * __watcall malloc(unsigned);
|
||||||
|
void __huge * __watcall halloc(long, unsigned);
|
||||||
|
# define acc_halloc(x) halloc(x,1)
|
||||||
|
# else
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define printf __builtin_printf
|
||||||
|
# define malloc(x) __builtin_malloc(x)
|
||||||
|
# define acc_halloc(x) malloc(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
>>> import pylzma; d="\1" + "\0"*131070 + "\2"; print len(d)
|
||||||
|
>>> c=pylzma.compress(d, eos=0)[5:]; print len(c), map(ord, c)
|
||||||
|
*/
|
||||||
|
static const unsigned char c_data[92] = {
|
||||||
|
0, 0, 128, 65, 72, 1, 140, 46, 188, 80, 161, 51, 135, 75, 212, 2, 20, 181, 241, 145, 230, 34, 107, 72, 201, 86, 118, 176, 70, 120, 214, 184, 247, 212, 250, 132, 59, 160, 44, 112, 185, 177, 245, 126, 103, 190, 14, 145, 73, 36, 148, 246, 166, 58, 41, 192, 68, 167, 144, 98, 122, 42, 61, 195, 135, 248, 98, 136, 254, 191, 96, 21, 192, 75, 86, 63, 228, 231, 15, 70, 52, 239, 169, 194, 249, 109, 126, 11, 123, 48, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
int r;
|
||||||
|
uint32_t src_len = sizeof(c_data);
|
||||||
|
uint32_t dst_len = 131072ul;
|
||||||
|
uint32_t src_out = 0;
|
||||||
|
uint32_t dst_out = 0;
|
||||||
|
const bytep src;
|
||||||
|
bytep dst;
|
||||||
|
CLzmaDecoderState *s;
|
||||||
|
|
||||||
|
printf("Decompress %lu %lu\n", (long)src_len, (long)dst_len);
|
||||||
|
s = (CLzmaDecoderState *) malloc(32768u);
|
||||||
|
src = c_data;
|
||||||
|
dst = (bytep) acc_halloc(dst_len);
|
||||||
|
if (!s || !dst) {
|
||||||
|
printf("ERROR: Out of memory!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (i = 0; i != dst_len; ++i)
|
||||||
|
dst[i] = 255;
|
||||||
|
|
||||||
|
s->Properties.lc = 3; s->Properties.lp = 0; s->Properties.pb = 2;
|
||||||
|
r = LzmaDecode(s, src, src_len, &src_out, dst, dst_len, &dst_out);
|
||||||
|
|
||||||
|
if (r != 0 || src_out != src_len || dst_out != dst_len)
|
||||||
|
{
|
||||||
|
printf("ERROR: Decompression error %d %lu %lu\n", r, (long)src_out, (long)dst_out);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
if (dst[i] != 1)
|
||||||
|
goto data_error;
|
||||||
|
while (++i != dst_len - 1)
|
||||||
|
if (dst[i] != 0)
|
||||||
|
goto data_error;
|
||||||
|
if (dst[i] != 2)
|
||||||
|
goto data_error;
|
||||||
|
|
||||||
|
printf("Decompression test passed. All done.\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
data_error:
|
||||||
|
printf("ERROR: Decompression data error at offset %lu.\n", (long)i);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* vim:set ts=4 et: */
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
; lzma_d.ash -- 16-bit assembly
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 2006-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; Markus F.X.J. Oberhumer
|
||||||
|
; <markus@oberhumer.com>
|
||||||
|
; http://www.oberhumer.com/opensource/upx/
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
; ------------- DECOMPRESSION -------------
|
||||||
|
|
||||||
|
; Input:
|
||||||
|
; ds:si - source
|
||||||
|
; es:di - dest
|
||||||
|
; cld
|
||||||
|
|
||||||
|
; Output:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// init
|
||||||
|
section LZMA_DEC00
|
||||||
|
//.byte 0xcc
|
||||||
|
|
||||||
|
mov bp, sp
|
||||||
|
#if 0
|
||||||
|
// DEBUG - check for enough stack
|
||||||
|
lea bx, [bp + lzma_stack_adjust - 256]
|
||||||
|
cmp bp, bx
|
||||||
|
1: jcs 1b
|
||||||
|
#endif
|
||||||
|
lea bx, [bp + lzma_stack_adjust]
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// clear stack
|
||||||
|
xor ax, ax
|
||||||
|
1: push ax
|
||||||
|
cmp sp, bx
|
||||||
|
jnzs 1b
|
||||||
|
#else
|
||||||
|
mov sp, bx
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inc si
|
||||||
|
inc si
|
||||||
|
|
||||||
|
push bx // &outSizeProcessed __near [bp + 24]
|
||||||
|
mov ax, offset lzma_u_len_hi // outSize
|
||||||
|
push ax // [bp + 22]
|
||||||
|
mov ax, offset lzma_u_len
|
||||||
|
push ax // [bp + 20]
|
||||||
|
push es // out [bp + 18]
|
||||||
|
push di // [bp + 16]
|
||||||
|
|
||||||
|
add bx, 4
|
||||||
|
push bx // &inSizeProcessed __near [bp + 14]
|
||||||
|
mov ax, offset lzma_c_len_hi // inSize
|
||||||
|
push ax // [bp + 12]
|
||||||
|
mov ax, offset lzma_c_len
|
||||||
|
push ax // [bp + 10]
|
||||||
|
push ds // in [bp + 8]
|
||||||
|
push si // [bp + 6]
|
||||||
|
|
||||||
|
add bx, 4
|
||||||
|
push bx // &state __near [bp + 4]
|
||||||
|
|
||||||
|
// enter small memory model
|
||||||
|
push ds // save ds && dummy for call
|
||||||
|
push ss
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
// fill properties
|
||||||
|
movw [bx], offset lzma_properties
|
||||||
|
movw [bx+2], offset lzma_properties_hi
|
||||||
|
|
||||||
|
ignore_reloc_overflow lzma_u_len
|
||||||
|
ignore_reloc_overflow lzma_c_len
|
||||||
|
ignore_reloc_overflow lzma_properties
|
||||||
|
|
||||||
|
|
||||||
|
#define ret
|
||||||
|
section LZMA_DEC10
|
||||||
|
.arch i8086, nojumps
|
||||||
|
#define SMALL 1
|
||||||
|
#include "lzma_m.h"
|
||||||
|
#include "lzma_d_cs.S"
|
||||||
|
#undef SMALL
|
||||||
|
section LZMA_DEC20
|
||||||
|
.arch i8086, nojumps
|
||||||
|
#define FAST 1
|
||||||
|
#include "lzma_m.h"
|
||||||
|
#include "lzma_d_cf.S"
|
||||||
|
#undef FAST
|
||||||
|
.arch i8086, jumps
|
||||||
|
#undef ret
|
||||||
|
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
section LZMA_DEC30
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
section LZMA_DEC31
|
||||||
|
// clear dirty stack
|
||||||
|
mov sp, bp
|
||||||
|
mov bx, offset clear_dirty_stack_low
|
||||||
|
xor ax, ax
|
||||||
|
1: push ax
|
||||||
|
cmp sp, bx
|
||||||
|
jnzs 1b
|
||||||
|
|
||||||
|
section LZMA_DEC32
|
||||||
|
mov sp, bp
|
||||||
|
mov di, offset lzma_u_len
|
||||||
|
ignore_reloc_overflow lzma_u_len
|
||||||
|
|
||||||
|
section LZMA_DEC33
|
||||||
|
pop ax
|
||||||
|
push ax
|
||||||
|
add ax, offset lzma_u_len_segment
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
|
||||||
|
// vi:ts=4:et
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,430 @@
|
|||||||
|
/*
|
||||||
|
; lzma_m.h -- 16-bit assembly
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 2006-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; Markus F.X.J. Oberhumer
|
||||||
|
; <markus@oberhumer.com>
|
||||||
|
; http://www.oberhumer.com/opensource/upx/
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __AHSHIFT
|
||||||
|
|
||||||
|
/* DOS real mode */
|
||||||
|
#define __AHSHIFT 12
|
||||||
|
#define __AHINCR (1 << __AHSHIFT) /* 4096 */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// support macros: PIA, PIS, PTS, PTC
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// huge pointer add: dx:ax = dx:ax + cx:bx
|
||||||
|
.macro M_PIA_small
|
||||||
|
add ax, bx
|
||||||
|
adc cx, 0
|
||||||
|
#if 0
|
||||||
|
// code size: 8 bytes
|
||||||
|
// i086: 2+4+56+3 == 65 clocks
|
||||||
|
// i286: 2+2+17+2 == 23 clocks
|
||||||
|
mov bx, cx
|
||||||
|
mov cl, __AHSHIFT
|
||||||
|
shl bx, cl
|
||||||
|
add dx, bx
|
||||||
|
#else
|
||||||
|
// code size: 8 bytes
|
||||||
|
// i086: 2+4+20+3 == 29 clocks
|
||||||
|
// i286: 2+2+ 9+2 == 15 clocks
|
||||||
|
mov bl, cl
|
||||||
|
mov cl, __AHSHIFT - 8
|
||||||
|
shl bl, cl
|
||||||
|
add dh, bl
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro M_PIA_fast
|
||||||
|
add ax, bx
|
||||||
|
adc cx, 0
|
||||||
|
// code size: 10 bytes
|
||||||
|
// i086: 4*2+3 == 11 clocks
|
||||||
|
// i286: 4*2+2 == 10 clocks
|
||||||
|
shl cl
|
||||||
|
shl cl
|
||||||
|
shl cl
|
||||||
|
shl cl
|
||||||
|
add dh, cl
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
.macro M_PIA1_small
|
||||||
|
// code size: 6 bytes
|
||||||
|
// i086: 3+16 == 19 clocks (jump taken)
|
||||||
|
// i286: 2+ 7+m ~~ 11 clocks (jump taken)
|
||||||
|
local L1
|
||||||
|
inc ax
|
||||||
|
jnes L1
|
||||||
|
//add dx, __AHINCR
|
||||||
|
add dh, __AHINCR >> 8
|
||||||
|
L1:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro M_PIA1_fast
|
||||||
|
// WARNING: this trashes "bx" !
|
||||||
|
// code size: 10 bytes
|
||||||
|
// i086: 3+3+3+3 == 12 clocks
|
||||||
|
// i286: 2+2+2+2 == 8 clocks
|
||||||
|
add ax, 1
|
||||||
|
sbb bl, bl
|
||||||
|
and bl, __AHINCR >> 8
|
||||||
|
add dh, bl
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// huge pointer sub: dx:ax = dx:ax - cx:bx
|
||||||
|
.macro M_PIS
|
||||||
|
sub ax, bx
|
||||||
|
adc cx, 0
|
||||||
|
mov bx, cx
|
||||||
|
mov cl, __AHSHIFT
|
||||||
|
shl bx, cl
|
||||||
|
sub dx, bx
|
||||||
|
.endm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// huge pointer diff: dx:ax = dx:ax - cx:bx
|
||||||
|
.macro M_PTS
|
||||||
|
#if 0
|
||||||
|
// normalize
|
||||||
|
// FIXME
|
||||||
|
// subtract
|
||||||
|
sub ax, bx
|
||||||
|
sbb dx, cx
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// huge pointer compare: set zero and carry flags: dx:ax cmp cx:bx
|
||||||
|
.macro M_PTC
|
||||||
|
// NOTE: no pointer normalization!
|
||||||
|
local L1
|
||||||
|
cmp dx, cx
|
||||||
|
jnes L1
|
||||||
|
cmp ax, bx
|
||||||
|
L1:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro M_PTC_JNE l
|
||||||
|
cmp ax, bx
|
||||||
|
jnes l
|
||||||
|
cmp dx, cx
|
||||||
|
jnes l
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// support macros: U4M, shld, shrd
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// umul32: dx:ax = dx:ax * 00:bx
|
||||||
|
.macro M_U4M_dxax_00bx
|
||||||
|
// mult high-word
|
||||||
|
mov cx, ax // save ax
|
||||||
|
mov ax, dx
|
||||||
|
mul bx
|
||||||
|
xchg ax, cx // save high-word result, get saved ax
|
||||||
|
// mult low-word
|
||||||
|
mul bx // dx:ax := ax * bx
|
||||||
|
// add high-word
|
||||||
|
add dx, cx // add high-word result
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// umul32: dx:ax = dx:ax * word ptr [bx]
|
||||||
|
.macro M_U4M_dxax_00bx_ptr
|
||||||
|
// mult high-word
|
||||||
|
mov cx, ax // save ax
|
||||||
|
mov ax, dx
|
||||||
|
mul word ptr [bx]
|
||||||
|
xchg ax, cx // save high-word result, get saved ax
|
||||||
|
// mult low-word
|
||||||
|
mul word ptr [bx]
|
||||||
|
// add high-word
|
||||||
|
add dx, cx // add high-word result
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// umul32: dx:ax = ax:cx * 00:bx
|
||||||
|
.macro M_U4M_axcx_00bx
|
||||||
|
// mult high-word
|
||||||
|
mul bx
|
||||||
|
xchg ax, cx // save high-word result, get low
|
||||||
|
// mult low-word
|
||||||
|
mul bx
|
||||||
|
// add high-word
|
||||||
|
add dx, cx // add high-word result
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// umul32: dx:ax = dx:ax * 0x0600
|
||||||
|
.macro M_U4M_dxax_0x0600
|
||||||
|
#if 0
|
||||||
|
// code size: 18 bytes
|
||||||
|
// i086: > 140 clocks (mul needs 70 clocks)
|
||||||
|
// i286: > 26 clocks (mul needs 13 clocks)
|
||||||
|
mov bx, 0x300
|
||||||
|
M_U4M_dxax_00bx
|
||||||
|
shl ax
|
||||||
|
rcl dx
|
||||||
|
#elif 0
|
||||||
|
// code size: 14 bytes
|
||||||
|
// i086: > 140 clocks (mul needs 70 clocks)
|
||||||
|
// i286: > 26 clocks (mul needs 13 clocks)
|
||||||
|
mov bx, 0x600
|
||||||
|
M_U4M_dxax_00bx
|
||||||
|
#else
|
||||||
|
// code size: 16+8 == 24 bytes
|
||||||
|
// i086: 18+9 == 27 clocks
|
||||||
|
// i286: 16+8 == 24 clocks
|
||||||
|
// FIXME: can we further optimize this ?
|
||||||
|
shl ax
|
||||||
|
rcl dx // dx:ax <<= 1 v * 2
|
||||||
|
mov cx, dx
|
||||||
|
mov bx, ax // cx:bx = dx:ax v * 2
|
||||||
|
shl ax
|
||||||
|
rcl dx // dx:ax <<= 1 v * 4
|
||||||
|
add ax, bx
|
||||||
|
adc dx, cx // dx:ax += cx:bx v * 6
|
||||||
|
M_shld_8 // dx:ax <<= 8 v * 0x600
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// shld: dx:ax <<= 8
|
||||||
|
.macro M_shld_8
|
||||||
|
// code size: 8 bytes
|
||||||
|
// i086: 9 clocks
|
||||||
|
// i286: 8 clocks
|
||||||
|
mov dh, dl
|
||||||
|
mov dl, ah
|
||||||
|
mov ah, al
|
||||||
|
xor al, al
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// shld: di:si <<= 8; bx and cx are free
|
||||||
|
.macro M_shld_disi_8_bxcx
|
||||||
|
#if 0
|
||||||
|
// code size: 9 bytes
|
||||||
|
// i086: 2 + 7*(2+2+18) + (2+2+5) == 165 clocks
|
||||||
|
// i286: 2 + 7*(2+2+10) + (2+2+4) == 108 clocks
|
||||||
|
local L1
|
||||||
|
mov cx, 8
|
||||||
|
L1: shl si
|
||||||
|
rcl di
|
||||||
|
loop L1
|
||||||
|
#else
|
||||||
|
// code size: 16 bytes
|
||||||
|
// i086: 17 clocks
|
||||||
|
// i286: 16 clocks
|
||||||
|
mov bx, di
|
||||||
|
mov cx, si
|
||||||
|
mov bh, bl
|
||||||
|
mov bl, ch
|
||||||
|
mov ch, cl
|
||||||
|
xor cl, cl
|
||||||
|
mov di, bx
|
||||||
|
mov si, cx
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// shld: di:ax <<= 8; bx and cx are free
|
||||||
|
.macro M_shld_diax_8_bxcx
|
||||||
|
#if 0
|
||||||
|
// code size: 9 bytes
|
||||||
|
// i086: 2 + 7*(2+2+18) + (2+2+5) == 165 clocks
|
||||||
|
// i286: 2 + 7*(2+2+10) + (2+2+4) == 108 clocks
|
||||||
|
local L1
|
||||||
|
mov cx, 8
|
||||||
|
L1: shl ax
|
||||||
|
rcl di
|
||||||
|
loop L1
|
||||||
|
#else
|
||||||
|
// code size: 12 bytes
|
||||||
|
// i086: 13 clocks
|
||||||
|
// i286: 12 clocks
|
||||||
|
mov bx, di
|
||||||
|
mov bh, bl
|
||||||
|
mov bl, ah
|
||||||
|
mov ah, al
|
||||||
|
xor al, al
|
||||||
|
mov di, bx
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
.macro M_shld_8_bp h l
|
||||||
|
mov dx, word ptr[bp+h]
|
||||||
|
mov ax, word ptr[bp+l]
|
||||||
|
M_shld_8
|
||||||
|
mov word ptr[bp+h], dx
|
||||||
|
mov word ptr[bp+l], ax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// shld: dx:ax <<= cl; trashes cl and register "r1" (bx, di, si or bp)
|
||||||
|
// REQUIRED: 0 <= cl <= 15
|
||||||
|
.macro M_shld_00_15 r1
|
||||||
|
mov r1, ax // save ax
|
||||||
|
shl dx, cl
|
||||||
|
shl ax, cl
|
||||||
|
sub cl, 16
|
||||||
|
neg cl // cl = 16 - cl
|
||||||
|
shr r1, cl
|
||||||
|
or dx, r1
|
||||||
|
.endm
|
||||||
|
|
||||||
|
// shld: dx:ax <<= cl; trashes cl
|
||||||
|
// REQUIRED: 16 <= cl <= 32
|
||||||
|
.macro M_shld_16_32
|
||||||
|
sub cl, 16
|
||||||
|
shl ax, cl
|
||||||
|
mov dx, ax
|
||||||
|
xor ax, ax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
// shld: dx:ax <<= cl; trashes cl and register "r1" (bx, di, si or bp)
|
||||||
|
// REQUIRED: 0 <= cl <= 32
|
||||||
|
.macro M_shld r1
|
||||||
|
local L1, L2
|
||||||
|
cmp cl, 16
|
||||||
|
jaes L1
|
||||||
|
// 0 <= cl <= 15
|
||||||
|
M_shld_00_15 r1
|
||||||
|
jmps L2
|
||||||
|
L1:
|
||||||
|
// 16 <= cl <= 32
|
||||||
|
M_shld_16_32
|
||||||
|
L2:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
// shld: dx:ax >>= 11
|
||||||
|
.macro M_shrd_11_small
|
||||||
|
// WARNING: this trashes "bx" !
|
||||||
|
// code size: 14 bytes
|
||||||
|
// i086: 4+2+52+52+4+28+3 == 145 clocks
|
||||||
|
// i286: 2+2+16+16+2+10+2 == 50 clocks
|
||||||
|
mov cl, 11
|
||||||
|
mov bx, dx // save dx
|
||||||
|
shr ax, cl
|
||||||
|
shr dx, cl
|
||||||
|
mov cl, 5 // cl = 16 - cl
|
||||||
|
shl bx, cl
|
||||||
|
or ax, bx
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro M_shrd_11_fast
|
||||||
|
// code size: 20 bytes
|
||||||
|
// i086: 21 clocks
|
||||||
|
// i286: 20 clocks
|
||||||
|
mov al, ah
|
||||||
|
mov ah, dl
|
||||||
|
mov dl, dh
|
||||||
|
xor dh, dh
|
||||||
|
shr dx
|
||||||
|
rcr ax
|
||||||
|
shr dx
|
||||||
|
rcr ax
|
||||||
|
shr dx
|
||||||
|
rcr ax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
.macro M_shrd_11_bp_small h l
|
||||||
|
mov dx, word ptr[bp+h]
|
||||||
|
mov ax, word ptr[bp+l]
|
||||||
|
M_shrd_11_small
|
||||||
|
mov word ptr[bp+h], dx
|
||||||
|
mov word ptr[bp+l], ax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro M_shrd_11_bp_fast h l
|
||||||
|
mov dx, word ptr[bp+h]
|
||||||
|
mov ax, word ptr[bp+l]
|
||||||
|
M_shrd_11_fast
|
||||||
|
mov word ptr[bp+h], dx
|
||||||
|
mov word ptr[bp+l], ax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
.macro M_shrd_11_disi_bp_small h l
|
||||||
|
mov dx, di
|
||||||
|
mov ax, si
|
||||||
|
M_shrd_11_small
|
||||||
|
mov word ptr[bp+h], dx
|
||||||
|
mov word ptr[bp+l], ax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro M_shrd_11_disi_bp_fast h l
|
||||||
|
mov dx, di
|
||||||
|
mov ax, si
|
||||||
|
M_shrd_11_fast
|
||||||
|
mov word ptr[bp+h], dx
|
||||||
|
mov word ptr[bp+l], ax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#endif /* ifndef __AHSHIFT */
|
||||||
|
|
||||||
|
|
||||||
|
#undef M_PIA
|
||||||
|
#undef M_PIA1
|
||||||
|
#undef M_shrd_11
|
||||||
|
#undef M_shrd_11_bp
|
||||||
|
#undef M_shrd_11_disi_bp
|
||||||
|
|
||||||
|
#if defined(FAST)
|
||||||
|
# define M_PIA M_PIA_fast
|
||||||
|
# define M_PIA1 M_PIA1_fast
|
||||||
|
# define M_shrd_11 M_shrd_11_fast
|
||||||
|
# define M_shrd_11_bp M_shrd_11_bp_fast
|
||||||
|
# define M_shrd_11_disi_bp M_shrd_11_disi_bp_fast
|
||||||
|
#elif defined(SMALL)
|
||||||
|
# define M_PIA M_PIA_small
|
||||||
|
# define M_PIA1 M_PIA1_small
|
||||||
|
# define M_shrd_11 M_shrd_11_small
|
||||||
|
# define M_shrd_11_bp M_shrd_11_bp_small
|
||||||
|
# define M_shrd_11_disi_bp M_shrd_11_disi_bp_small
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// vi:ts=4:et
|
||||||
@@ -41,6 +41,14 @@
|
|||||||
.macro section name
|
.macro section name
|
||||||
.section \name
|
.section \name
|
||||||
.code16
|
.code16
|
||||||
|
.set current_section,\name
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ignore_reloc_overflow sym
|
||||||
|
.pushsection ignore_reloc_overflow
|
||||||
|
.byte \sym
|
||||||
|
.byte current_section
|
||||||
|
.popsection
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro CPU id
|
.macro CPU id
|
||||||
@@ -120,6 +128,7 @@
|
|||||||
.byte 0x7f, \target - . - 1
|
.byte 0x7f, \target - . - 1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
#define jaes jncs
|
||||||
#define jbes jnas
|
#define jbes jnas
|
||||||
#define jbs jcs
|
#define jbs jcs
|
||||||
#define jes jzs
|
#define jes jzs
|
||||||
@@ -158,6 +167,7 @@ section CALLTRI2
|
|||||||
lodsw
|
lodsw
|
||||||
loop cjt16_L1
|
loop cjt16_L1
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
; =============
|
; =============
|
||||||
*/
|
*/
|
||||||
@@ -193,6 +203,7 @@ section CALLTRI6
|
|||||||
cjt16_L2:
|
cjt16_L2:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
; vi:ts=8:et:nowrap
|
; vi:ts=8:et:nowrap
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,6 +37,10 @@
|
|||||||
; bp - -1
|
; bp - -1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef COPY_MATCH
|
||||||
|
# define COPY_MATCH rep movsb
|
||||||
|
#endif
|
||||||
|
|
||||||
section NRV2B160
|
section NRV2B160
|
||||||
literal_n2b:
|
literal_n2b:
|
||||||
movsb
|
movsb
|
||||||
@@ -79,8 +83,7 @@ section NRVGTD00
|
|||||||
section NRVDECO2
|
section NRVDECO2
|
||||||
lea ax, [bp+di]
|
lea ax, [bp+di]
|
||||||
xchg ax, si
|
xchg ax, si
|
||||||
rep
|
COPY_MATCH
|
||||||
movsb
|
|
||||||
xchg ax, si
|
xchg ax, si
|
||||||
jmps decomp_start_n2b
|
jmps decomp_start_n2b
|
||||||
getbit_cx_n2b:
|
getbit_cx_n2b:
|
||||||
@@ -105,6 +108,5 @@ decomp_done_n2b:
|
|||||||
|
|
||||||
cjt16 decomp_ret_n2b
|
cjt16 decomp_ret_n2b
|
||||||
|
|
||||||
/*
|
|
||||||
; vi:ts=8:et
|
/* vim:set ts=4 et: */
|
||||||
*/
|
|
||||||
|
|||||||
@@ -152,5 +152,5 @@ f2_n2b:
|
|||||||
ret
|
ret
|
||||||
decomp_done_n2b:
|
decomp_done_n2b:
|
||||||
|
|
||||||
/* vi:ts=8:et */
|
|
||||||
|
|
||||||
|
/* vim:set ts=4 et: */
|
||||||
|
|||||||
@@ -162,5 +162,5 @@ f2_n2d:
|
|||||||
ret
|
ret
|
||||||
decomp_done_n2d:
|
decomp_done_n2d:
|
||||||
|
|
||||||
/* vi:ts=8:et */
|
|
||||||
|
|
||||||
|
/* vim:set ts=4 et: */
|
||||||
|
|||||||
@@ -168,4 +168,5 @@ f2_n2e:
|
|||||||
ret
|
ret
|
||||||
decomp_done_n2e:
|
decomp_done_n2e:
|
||||||
|
|
||||||
/* vi:ts=8:et */
|
|
||||||
|
/* vim:set ts=4 et: */
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# wdis2gas.py --
|
||||||
|
#
|
||||||
|
# This file is part of the UPX executable compressor.
|
||||||
|
#
|
||||||
|
# Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# UPX and the UCL library are free software; you can redistribute them
|
||||||
|
# and/or modify them under the terms of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation; either version 2 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; see the file COPYING.
|
||||||
|
# If not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
# <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
import getopt, os, re, string, sys
|
||||||
|
|
||||||
|
|
||||||
|
class opts:
|
||||||
|
arch = "i086"
|
||||||
|
label_prefix = ".L"
|
||||||
|
verbose = 0
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // main
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
shortopts, longopts = "qv", [
|
||||||
|
"arch", "label-prefix=", "quiet", "verbose"
|
||||||
|
]
|
||||||
|
xopts, args = getopt.gnu_getopt(argv[1:], shortopts, longopts)
|
||||||
|
for opt, optarg in xopts:
|
||||||
|
if 0: pass
|
||||||
|
elif opt in ["-q", "--quiet"]: opts.verbose = opts.verbose - 1
|
||||||
|
elif opt in ["-v", "--verbose"]: opts.verbose = opts.verbose + 1
|
||||||
|
elif opt in ["--arch"]: opts.arch = optarg
|
||||||
|
elif opt in ["--label-prefix"]: opts.label_prefix = optarg
|
||||||
|
else: assert 0, ("getopt problem:", opt, optarg, xopts, args)
|
||||||
|
|
||||||
|
#
|
||||||
|
assert len(args) == 2
|
||||||
|
ifile = args[0]
|
||||||
|
ofile = args[1]
|
||||||
|
# read ifile
|
||||||
|
lines = open(ifile, "rb").readlines()
|
||||||
|
lines = map(string.rstrip, lines)
|
||||||
|
#
|
||||||
|
section = None
|
||||||
|
func = None
|
||||||
|
olines = []
|
||||||
|
for i in range(len(lines)):
|
||||||
|
l = lines[i]
|
||||||
|
if not l: continue
|
||||||
|
m = re.search(r"^No disassembly errors", l)
|
||||||
|
if m: continue
|
||||||
|
m = re.search(r"^Module:", l)
|
||||||
|
if m: continue
|
||||||
|
m = re.search(r"^GROUP:", l)
|
||||||
|
if m: continue
|
||||||
|
m = re.search(r"^(BSS|Routine) Size:", l)
|
||||||
|
if m: continue
|
||||||
|
m = re.search(r"^Segment:\s+(.+)\s+([0-9a-fA-F]+)\s+bytes$", l)
|
||||||
|
if m:
|
||||||
|
s = re.split(r"\s+", m.group(1))
|
||||||
|
assert len(s) == 3, (i, l, s, m.groups())
|
||||||
|
section = s
|
||||||
|
func = None
|
||||||
|
continue
|
||||||
|
m = re.search(r"^Comdat:\s+(.+)\s+SEGMENT NONE '(\w+)'\s+([0-9a-fA-F]+)\s+bytes$", l)
|
||||||
|
if m:
|
||||||
|
section = [m.group(2)]
|
||||||
|
assert section[0].endswith("_TEXT"), (i, l, section)
|
||||||
|
func = re.sub(r"^[_@]+|[_@]+$", "", m.group(1))
|
||||||
|
olines.append(".section .text." + func)
|
||||||
|
continue
|
||||||
|
assert section, (i, l)
|
||||||
|
m = re.search(r"^0000\s+(\w+):$", l)
|
||||||
|
if m:
|
||||||
|
assert section[0].endswith("_TEXT"), (i, l, section)
|
||||||
|
func = re.sub(r"^[_@]+|[_@]+$", "", m.group(1))
|
||||||
|
olines.append(".section .text." + func)
|
||||||
|
continue
|
||||||
|
assert func, (i, l, section)
|
||||||
|
m = re.search(r"^[0-9a-fA-F]{4}\s+L\$(\d+):$", l)
|
||||||
|
if m:
|
||||||
|
olines.append(opts.label_prefix + m.group(1) + ":")
|
||||||
|
continue
|
||||||
|
m = re.search(r"^[0-9a-fA-F]{4} (([0-9a-fA-F]{2} )+)\s+(.+)$", l)
|
||||||
|
assert m, (i, l)
|
||||||
|
if m.group(3).startswith("call"):
|
||||||
|
s = re.split(r"\s+", m.group(3))
|
||||||
|
assert len(s) == 2, (i, l, s, m.groups())
|
||||||
|
f = re.sub(r"^[@]+|[@]+$", "", s[1])
|
||||||
|
olines.append(" call " + f)
|
||||||
|
elif 1:
|
||||||
|
s = m.group(3).strip()
|
||||||
|
s = re.sub(r"L\$(\d+)", opts.label_prefix + r"\g<1>", s)
|
||||||
|
olines.append(" " + s)
|
||||||
|
else:
|
||||||
|
s = re.split(r"\s+", m.group(1).strip())
|
||||||
|
assert 1 <= len(s) <= 5, (i, l, s, m.groups())
|
||||||
|
s = ["0x" + x for x in s]
|
||||||
|
olines.append(" .byte " + ",".join(s))
|
||||||
|
|
||||||
|
|
||||||
|
# write ofile
|
||||||
|
ofp = open(ofile, "wb")
|
||||||
|
ofp.write(".code16\n")
|
||||||
|
ofp.write(".intel_syntax noprefix\n")
|
||||||
|
if opts.arch in ["i086", "8086", "i8086"]:
|
||||||
|
ofp.write(".arch i8086, jumps\n")
|
||||||
|
elif opts.arch in ["i286"]:
|
||||||
|
ofp.write(".arch i286, jumps\n")
|
||||||
|
else:
|
||||||
|
assert 0, ("invalid arch", opts.arch)
|
||||||
|
if 0:
|
||||||
|
for sym in ["__AHSHIFT", "__AHINCR", "__LMUL", "__aNahdiff"]:
|
||||||
|
ofp.write(".extern %s\n" % (sym))
|
||||||
|
ofp.write(".type %s,@function\n" % (sym))
|
||||||
|
ofp.write(".size %s,2\n" % (sym))
|
||||||
|
for l in olines:
|
||||||
|
ofp.write(l.rstrip() + "\n")
|
||||||
|
ofp.close()
|
||||||
|
##print olines
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main(sys.argv))
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
|
|||||||
@@ -300,8 +300,10 @@ ctend:
|
|||||||
// 2nd param: where is cto8 (dl, bl, or literal)
|
// 2nd param: where is cto8 (dl, bl, or literal)
|
||||||
|
|
||||||
section ctok32.00
|
section ctok32.00
|
||||||
|
.ifnc \addvalue, 0
|
||||||
.ifc \addvalue, edi
|
.ifc \addvalue, edi
|
||||||
mov esi, \addvalue
|
mov esi, edi
|
||||||
|
.endif
|
||||||
.endif
|
.endif
|
||||||
jmps ckstart
|
jmps ckstart
|
||||||
ckloop3:
|
ckloop3:
|
||||||
@@ -333,7 +335,11 @@ ckmark:
|
|||||||
|
|
||||||
sub eax, edi
|
sub eax, edi
|
||||||
.ifnc \addvalue, 0
|
.ifnc \addvalue, 0
|
||||||
|
.ifc \addvalue, edi
|
||||||
add eax, esi
|
add eax, esi
|
||||||
|
.else
|
||||||
|
add eax, \addvalue
|
||||||
|
.endif
|
||||||
.endif
|
.endif
|
||||||
mov [edi], eax
|
mov [edi], eax
|
||||||
add edi, 4
|
add edi, 4
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
@@ -55,7 +56,7 @@ $c += -fmodulo-sched
|
|||||||
$c += -floop-optimize2
|
$c += -floop-optimize2
|
||||||
$c += -ffixed-30
|
$c += -ffixed-30
|
||||||
else ifneq ($(findstring -gcc-4.2.0,$(firstword $($c))),)
|
else ifneq ($(findstring -gcc-4.2.0,$(firstword $($c))),)
|
||||||
# gcc-4.2.0-20060826 snapshot
|
# gcc-4.2.0-20060826.tar.bz2 snapshot
|
||||||
$c += -fno-wrapv
|
$c += -fno-wrapv
|
||||||
$c += -mtune=r4000
|
$c += -mtune=r4000
|
||||||
$c += -fno-regmove
|
$c += -fno-regmove
|
||||||
@@ -68,7 +69,9 @@ $c += -ffixed-30
|
|||||||
else
|
else
|
||||||
$(error unknown gcc version: $(firstword $($c)))
|
$(error unknown gcc version: $(firstword $($c)))
|
||||||
endif
|
endif
|
||||||
|
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||||
$c += -I$(UPX_LZMADIR)
|
$c += -I$(UPX_LZMADIR)
|
||||||
|
endif
|
||||||
$c += -I$(top_srcdir)/src
|
$c += -I$(top_srcdir)/src
|
||||||
|
|
||||||
lzma_d_c%.S : lzma_d_c.c
|
lzma_d_c%.S : lzma_d_c.c
|
||||||
@@ -84,7 +87,7 @@ lzma_d_cs.% : PP_FLAGS = -DSMALL
|
|||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // test-stub-compression (needs UPX_UCLPACK)
|
# // test-stub-compression (needs UPX_UCL_UCLPACK)
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
define __test_stub_compression
|
define __test_stub_compression
|
||||||
@@ -93,11 +96,13 @@ define __test_stub_compression
|
|||||||
@rm -f $1.tmp.*
|
@rm -f $1.tmp.*
|
||||||
@bzip2 -9 < $1 > $1.tmp.bz2
|
@bzip2 -9 < $1 > $1.tmp.bz2
|
||||||
@gzip -9mn < $1 > $1.tmp.gz
|
@gzip -9mn < $1 > $1.tmp.gz
|
||||||
$(if $(UPX_UCLPACK),@$(UPX_UCLPACK) --nrv2b --10 $1 $1.tmp.uclpack-nrv2b | egrep ' into ')
|
$(if $(UPX_UCL_UCLPACK),@$(UPX_UCL_UCLPACK) --nrv2b --10 $1 $1.tmp.uclpack-nrv2b | egrep ' into ')
|
||||||
@ls -l $1.tmp.*
|
@ls -l $1.tmp.*
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||||
test-stub-compression: tc_list = mipsel.r3000-ps1 default
|
test-stub-compression: tc_list = mipsel.r3000-ps1 default
|
||||||
test-stub-compression: lzma_d_cf.S lzma_d_cs.S
|
test-stub-compression: lzma_d_cf.S lzma_d_cs.S
|
||||||
$(call __test_stub_compression,tmp/lzma_d_cs.out,tmp/lzma_d_cs.o)
|
$(call __test_stub_compression,tmp/lzma_d_cs.out,tmp/lzma_d_cs.o)
|
||||||
.PHONY: test-stub-compression
|
.PHONY: test-stub-compression
|
||||||
|
endif
|
||||||
|
|||||||
@@ -34,11 +34,15 @@
|
|||||||
#ifndef _MR3K_STD_CONF_
|
#ifndef _MR3K_STD_CONF_
|
||||||
#define _MR3K_STD_CONF_
|
#define _MR3K_STD_CONF_
|
||||||
|
|
||||||
|
#define JOHN 1
|
||||||
|
#define ALT_SMALL 1
|
||||||
|
|
||||||
|
|
||||||
;//////////////////////////////////////
|
;//////////////////////////////////////
|
||||||
;// register defines
|
;// register defines
|
||||||
;//////////////////////////////////////
|
;//////////////////////////////////////
|
||||||
|
|
||||||
|
#if 1
|
||||||
#define tmp at
|
#define tmp at
|
||||||
|
|
||||||
#define dst t0
|
#define dst t0
|
||||||
@@ -58,6 +62,31 @@
|
|||||||
#define m_off t7
|
#define m_off t7
|
||||||
#define m_pos t7
|
#define m_pos t7
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
.print "\nwarning redefined src / dst\n"
|
||||||
|
|
||||||
|
#define tmp v1
|
||||||
|
|
||||||
|
#define src a0
|
||||||
|
#define dst a1
|
||||||
|
|
||||||
|
#define pc v0
|
||||||
|
#define cnt a2
|
||||||
|
|
||||||
|
#define src_ilen src
|
||||||
|
#define bb t1
|
||||||
|
#define ilen t2
|
||||||
|
#define last_m_off t3
|
||||||
|
#define m_len t4
|
||||||
|
#define bc t5
|
||||||
|
|
||||||
|
#define var t6
|
||||||
|
#define m_off t7
|
||||||
|
#define m_pos t7
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
;//////////////////////////////////////
|
;//////////////////////////////////////
|
||||||
;// init bitaccess
|
;// init bitaccess
|
||||||
@@ -89,12 +118,32 @@
|
|||||||
|
|
||||||
.macro init
|
.macro init
|
||||||
|
|
||||||
|
init_sz = .
|
||||||
|
|
||||||
|
.if (JOHN == 0)
|
||||||
move bc,zero
|
move bc,zero
|
||||||
|
|
||||||
|
.else // John's method
|
||||||
|
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
.if (ALT_SMALL == 1)
|
||||||
|
lui bc,1 << (31 - 16)
|
||||||
|
move bb,bc
|
||||||
|
.else
|
||||||
|
move bc,zero
|
||||||
|
.endif
|
||||||
|
.else
|
||||||
|
lui bc,1 << (31 - 16)
|
||||||
|
move bb,bc
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
li last_m_off,1
|
li last_m_off,1
|
||||||
.if (src != src_ilen)
|
.if (src != src_ilen)
|
||||||
move src_ilen,src
|
move src_ilen,src
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
init_sz = . - init_sz
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
@@ -104,6 +153,7 @@
|
|||||||
|
|
||||||
.macro ADDBITS
|
.macro ADDBITS
|
||||||
|
|
||||||
|
.if (JOHN == 0)
|
||||||
.if (UCL_SMALL == 1)
|
.if (UCL_SMALL == 1)
|
||||||
addiu bc, -1
|
addiu bc, -1
|
||||||
bltz bc, 2b
|
bltz bc, 2b
|
||||||
@@ -112,32 +162,92 @@
|
|||||||
addiu bc, -1
|
addiu bc, -1
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.else // John's method
|
||||||
|
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
.if (ALT_SMALL == 1)
|
||||||
|
beq bc,bb,2b # detect flag bit [empty]
|
||||||
|
.else
|
||||||
|
addiu bc,-1
|
||||||
|
bltz bc,2b
|
||||||
|
.endif
|
||||||
|
.else
|
||||||
|
srl var,bb,31 # var= most significant bit of bb
|
||||||
|
bne bc,bb,2f # detect flag bit [empty]
|
||||||
|
sll bb,1
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro ADDBITS_DONE
|
.macro ADDBITS_DONE
|
||||||
|
|
||||||
|
.if (JOHN == 0)
|
||||||
srlv var,bb,bc
|
srlv var,bb,bc
|
||||||
.if (UCL_SMALL == 1)
|
.if (UCL_SMALL == 1)
|
||||||
jr ra
|
jr ra
|
||||||
.endif
|
.endif
|
||||||
andi var,0x0001
|
andi var,0x0001
|
||||||
|
|
||||||
|
.else // John's method
|
||||||
|
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
.if (ALT_SMALL == 1)
|
||||||
|
srl var,bb,31 # var= most significant bit of bb
|
||||||
|
jr ra
|
||||||
|
sll bb,1
|
||||||
|
.else
|
||||||
|
srlv var,bb,bc
|
||||||
|
jr ra
|
||||||
|
andi var,0x0001
|
||||||
|
.endif
|
||||||
|
.else
|
||||||
|
.if (UCL_NRV_BB == 8)
|
||||||
|
sll bb,1
|
||||||
|
addiu bb,1 # the flag bit
|
||||||
|
srl var,bb,8 # var= most significant bit of bb
|
||||||
|
sll bb,24 # left-justify in register
|
||||||
|
.else
|
||||||
|
srl var,bb,31 # var= most significant bit of bb
|
||||||
|
sll bb,1
|
||||||
|
addiu bb,1
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro FILLBYTES_8
|
.macro FILLBYTES_8
|
||||||
|
|
||||||
.if (UCL_SMALL == 1)
|
.if (JOHN == 0)
|
||||||
li bc,8
|
|
||||||
.else
|
|
||||||
li bc,7
|
li bc,7
|
||||||
.endif
|
|
||||||
lbu bb,0(src_ilen)
|
lbu bb,0(src_ilen)
|
||||||
addiu src_ilen,1
|
addiu src_ilen,1
|
||||||
|
|
||||||
|
.else // John's method
|
||||||
|
|
||||||
|
.if (ALT_SMALL == 0)
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
li bc,8
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
lbu bb,0(src_ilen)
|
||||||
|
addiu src_ilen,1
|
||||||
|
.if ((ALT_SMALL == 1) && (UCL_SMALL == 1))
|
||||||
|
sll bb,1
|
||||||
|
addiu bb,1 # the flag bit
|
||||||
|
sll bb,24-1 # left-justify in register
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
.macro FILLBYTES_32
|
.macro FILLBYTES_32
|
||||||
|
|
||||||
|
.if (JOHN == 0)
|
||||||
.if (UCL_SMALL == 1)
|
.if (UCL_SMALL == 1)
|
||||||
li bc,32
|
li bc,32
|
||||||
.else
|
.else
|
||||||
@@ -147,9 +257,27 @@
|
|||||||
lwl bb,3(src_ilen)
|
lwl bb,3(src_ilen)
|
||||||
addiu src_ilen,4
|
addiu src_ilen,4
|
||||||
|
|
||||||
|
.else // John's method
|
||||||
|
|
||||||
|
.if (ALT_SMALL == 0)
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
li bc,32
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
lwr bb,0(src_ilen)
|
||||||
|
lwl bb,3(src_ilen)
|
||||||
|
addiu src_ilen,4
|
||||||
|
.if ((ALT_SMALL == 1) && (UCL_SMALL == 1))
|
||||||
|
srl var,bb,31 # var= most significant bit of bb
|
||||||
|
sll bb,1
|
||||||
|
jr ra
|
||||||
|
addiu bb,1
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro FILLBYTES
|
.macro FILLBITS
|
||||||
|
|
||||||
.if (UCL_NRV_BB == 8)
|
.if (UCL_NRV_BB == 8)
|
||||||
FILLBYTES_8
|
FILLBYTES_8
|
||||||
@@ -159,79 +287,29 @@
|
|||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
// This alternate for UCL_SMALL is 1 cycle faster for most getbit
|
|
||||||
// at a cost of 1 cycle (32 bits) or 3 cycles (8 bits) during refill.
|
|
||||||
// [Refill could save 1 cycle if MIPS had "set CarryIn" for ADD or SHIFT.]
|
|
||||||
// Call 'getbit'; it returns the next bit (0 or 1), in register 'var'.
|
|
||||||
// Register 'bb' is the bit buffer; register 'bc' contains the 'empty' value.
|
|
||||||
// The cases for widths 8 and 32 are not as similar as before,
|
|
||||||
// and 64-bit registers would require other code.
|
|
||||||
// But it is 1 cycle faster 31/32 of the time.
|
|
||||||
// [Indentation after control transfer emphasizes delay slot.]
|
|
||||||
//
|
|
||||||
//init:
|
|
||||||
// lui bc,1<<(31 - 16) # 1<<31 the flag bit
|
|
||||||
// lui bb,1<<(31 - 16) # 1<<31 empty
|
|
||||||
//--
|
|
||||||
// .if (8==UCL_NRV_BB)
|
|
||||||
//refill:
|
|
||||||
// lbu bb,0(src_ilen)
|
|
||||||
// addiu src_len,1
|
|
||||||
// sll bb,1
|
|
||||||
// ori bb,1 # the flag bit
|
|
||||||
// sll bb,24-1 # left-justify in register
|
|
||||||
// // falling through the 'beq' below saves 3 words of space
|
|
||||||
// .endif
|
|
||||||
//getbit:
|
|
||||||
// beq bc,bb,refill # detect flag bit [empty]
|
|
||||||
// srl var,bb,31 # var= most significant bit of bb
|
|
||||||
// jr ra
|
|
||||||
// sll bb,1
|
|
||||||
// .if (32==UCL_NRV_BB)
|
|
||||||
//refill:
|
|
||||||
// lwr bb,0(src_ilen)
|
|
||||||
// lwl bb,3(src_ilen)
|
|
||||||
// addiu src_ilen,4
|
|
||||||
// srl var,bb,31 # var= most significant bit of bb
|
|
||||||
// sll bb,1
|
|
||||||
// jr ra
|
|
||||||
// ori bb,1 # the flag bit
|
|
||||||
// .endif
|
|
||||||
|
|
||||||
// 2006-09-06 Faster by 3 cycles for inline expansion:
|
|
||||||
// beq bc,bb,7f # detect flag bit [empty]
|
|
||||||
// srl var,bb,31 # var= most significant bit of bb
|
|
||||||
// sll bb,1
|
|
||||||
//6:
|
|
||||||
// .subsection 1 # somewhere out-of-line
|
|
||||||
//7:
|
|
||||||
// b refill
|
|
||||||
// addi ra,r_bd_base,6b - bd_base # return past the 'sll' above
|
|
||||||
// .subsection 0 # return to main in-line code
|
|
||||||
//
|
|
||||||
// which is 3 cycles usually, +2 cycles for entering refill,
|
|
||||||
// +8 bytes (2 instructions) per getbit [7 in nrv2b, 9 in nrv2e]
|
|
||||||
// and requires another register r_bd_base which holds a handy
|
|
||||||
// address within +/- 32KB of the returns from refill.
|
|
||||||
//
|
|
||||||
|
|
||||||
.macro GBIT
|
.macro GBIT
|
||||||
|
|
||||||
.if (UCL_SMALL == 1)
|
.if (UCL_SMALL == 1)
|
||||||
2:
|
2:
|
||||||
FILLBYTES
|
FILLBITS
|
||||||
1:
|
1:
|
||||||
ADDBITS
|
ADDBITS
|
||||||
ADDBITS_DONE
|
ADDBITS_DONE
|
||||||
.else
|
.else
|
||||||
ADDBITS
|
ADDBITS
|
||||||
FILLBYTES
|
FILLBITS
|
||||||
|
.if (JOHN == 1)
|
||||||
|
ADDBITS_DONE
|
||||||
|
2:
|
||||||
|
.else
|
||||||
2:
|
2:
|
||||||
ADDBITS_DONE
|
ADDBITS_DONE
|
||||||
|
.endif
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
;//////////////////////////////////////
|
;//////////////////////////////////////
|
||||||
;// getbit call macro for SMALL version
|
;// getbit call macro for SMALL version
|
||||||
;//////////////////////////////////////
|
;//////////////////////////////////////
|
||||||
@@ -247,8 +325,23 @@
|
|||||||
.ifb p1
|
.ifb p1
|
||||||
bal t // gb_sub
|
bal t // gb_sub
|
||||||
.else
|
.else
|
||||||
|
|
||||||
|
.if (JOHN == 0)
|
||||||
bal t+4 // gb_sub+4
|
bal t+4 // gb_sub+4
|
||||||
addiu bc,-1
|
addiu bc,-1
|
||||||
|
|
||||||
|
.else // John's method
|
||||||
|
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
.if (ALT_SMALL == 0)
|
||||||
|
bal t+4 // gb_sub+4
|
||||||
|
addiu bc,-1
|
||||||
|
.else
|
||||||
|
bal t // gb_sub+4
|
||||||
|
nop
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
.endif
|
.endif
|
||||||
.else
|
.else
|
||||||
GBIT
|
GBIT
|
||||||
@@ -271,20 +364,20 @@
|
|||||||
.endif
|
.endif
|
||||||
\type decomp_done
|
\type decomp_done
|
||||||
.if (UCL_SMALL == 1)
|
.if (UCL_SMALL == 1)
|
||||||
WITHOUT_SUB = 0
|
|
||||||
GBIT
|
GBIT
|
||||||
.endif
|
.endif
|
||||||
.else
|
.else
|
||||||
.ifc "\option", "sub_only"
|
.ifc "\option", "sub_only"
|
||||||
|
|
||||||
2:
|
2:
|
||||||
FILLBYTES
|
FILLBITS
|
||||||
.ifnb label
|
.ifnb label
|
||||||
.global \label
|
.global \label
|
||||||
\label:
|
\label:
|
||||||
.endif
|
.endif
|
||||||
ADDBITS
|
ADDBITS
|
||||||
ADDBITS_DONE
|
ADDBITS_DONE
|
||||||
|
|
||||||
.else
|
.else
|
||||||
.ifc "\option", "without_sub"
|
.ifc "\option", "without_sub"
|
||||||
.if (UCL_SMALL == 1)
|
.if (UCL_SMALL == 1)
|
||||||
@@ -309,12 +402,12 @@
|
|||||||
|
|
||||||
.macro uclmcpy ret
|
.macro uclmcpy ret
|
||||||
|
|
||||||
local wordchk, bcpy
|
local wordchk, prepbcpy
|
||||||
local bcpy_chk, skip
|
local bcopy, skip
|
||||||
|
|
||||||
.if (UCL_FAST == 1)
|
.if (UCL_FAST == 1)
|
||||||
slti var,m_off,4
|
slti var,m_off,4
|
||||||
bnez var,bcpy
|
bnez var,prepbcpy
|
||||||
subu m_pos,dst,m_off
|
subu m_pos,dst,m_off
|
||||||
wordchk:
|
wordchk:
|
||||||
slti var,m_len,4
|
slti var,m_len,4
|
||||||
@@ -327,22 +420,66 @@ wordchk:
|
|||||||
addiu m_pos,4
|
addiu m_pos,4
|
||||||
bnez m_len,wordchk
|
bnez m_len,wordchk
|
||||||
addiu dst,4
|
addiu dst,4
|
||||||
|
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
.if (WITHOUT_SUB == 1)
|
||||||
|
t = gb_e
|
||||||
|
.else
|
||||||
|
t = 1f
|
||||||
|
.endif
|
||||||
|
.if (1 == 1)
|
||||||
b \ret
|
b \ret
|
||||||
nop
|
nop
|
||||||
|
.else
|
||||||
|
bal t
|
||||||
|
addiu ra, (\ret + 4) - (. + 4)
|
||||||
|
.endif
|
||||||
.else
|
.else
|
||||||
subu m_pos,dst,m_off
|
.if (JOHN == 0)
|
||||||
|
b \ret
|
||||||
|
nop
|
||||||
|
.else
|
||||||
|
b \ret + 4
|
||||||
|
srl var,bb,31 # var= most significant bit of bb
|
||||||
|
.endif
|
||||||
.endif
|
.endif
|
||||||
bcpy_chk:
|
prepbcpy:
|
||||||
beqz m_len,\ret
|
.else
|
||||||
bcpy:
|
subu m_pos,dst,m_off
|
||||||
|
.endif
|
||||||
|
bcopy:
|
||||||
lbu var,0(m_pos)
|
lbu var,0(m_pos)
|
||||||
skip:
|
skip:
|
||||||
addiu m_len,-1
|
addiu m_len,-1
|
||||||
sb var,0(dst)
|
|
||||||
addiu m_pos,1
|
addiu m_pos,1
|
||||||
b bcpy_chk
|
|
||||||
addiu dst,1
|
addiu dst,1
|
||||||
|
bnez m_len,bcopy
|
||||||
|
sb var,-1(dst)
|
||||||
|
|
||||||
|
.if (UCL_SMALL == 1)
|
||||||
|
.if (WITHOUT_SUB == 1)
|
||||||
|
t = gb_e
|
||||||
|
.else
|
||||||
|
t = 1f
|
||||||
|
.endif
|
||||||
|
.if (1 == 1)
|
||||||
|
b \ret
|
||||||
|
nop
|
||||||
|
.else
|
||||||
|
bal t
|
||||||
|
addiu ra, (\ret + 4) - (. + 4)
|
||||||
|
.endif
|
||||||
|
.else
|
||||||
|
.if (JOHN == 0)
|
||||||
|
b \ret
|
||||||
|
nop
|
||||||
|
.else
|
||||||
|
b \ret + 4
|
||||||
|
srl var,bb,31 # var= most significant bit of bb
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
||||||
#endif //_MR3K_STD_CONF_
|
#endif //_MR3K_STD_CONF_
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ __dir_list += ../../../../../.. ../../../../../../.. ../../../../../../../..
|
|||||||
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
|
||||||
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
|
||||||
endif
|
endif
|
||||||
|
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
|
||||||
vpath %.c $(top_srcdir)/src/stub/src/c
|
vpath %.c $(top_srcdir)/src/stub/src/c
|
||||||
|
|
||||||
STUBS =
|
STUBS =
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ copy:
|
|||||||
sub r10,r12,r9 // &b_info
|
sub r10,r12,r9 // &b_info
|
||||||
add r10,r10,r4 // relocated &b_info
|
add r10,r10,r4 // relocated &b_info
|
||||||
|
|
||||||
ldrb r0,[r11,# b_method ] // 5th param
|
ldr r0,[r11,# b_method ] // 5th param (whole word: endian issues!)
|
||||||
stmdb sp!,{r0,lr}
|
stmdb sp!,{r0,lr}
|
||||||
ldr r3,[r11,# sz_unc]
|
ldr r3,[r11,# sz_unc]
|
||||||
add r0, r11,# sz_b_info
|
add r0, r11,# sz_b_info
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
; armeb-linux.kernel.vmlinux-head.S -- set up stack for vmlinux/armeb format
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 2006-2007 John Reiser
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; John Reiser
|
||||||
|
; <jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arm-linux.kernel.vmlinux-head.S"
|
||||||
|
|
||||||
|
// vi:ts=8:et:nowrap
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
; armeb-linux.kernel.vmlinux.S -- loader & decompressor for the vmlinux/armeb format
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
; Copyright (C) 1996-2007 Laszlo Molnar
|
||||||
|
; Copyright (C) 2004-2007 John Reiser
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
;
|
||||||
|
; John Reiser
|
||||||
|
; <jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arm-linux.kernel.vmlinux.S"
|
||||||
|
|
||||||
|
// vi:ts=8:et:nowrap
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define ACC_LIBC_NAKED 1
|
#define ACC_LIBC_NAKED 1
|
||||||
#define ACC_OS_FREESTANDING 1
|
/*#define ACC_OS_FREESTANDING 1*/
|
||||||
#include "miniacc.h"
|
#include "miniacc.h"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -39,6 +39,15 @@
|
|||||||
#undef _LZMA_PROB32
|
#undef _LZMA_PROB32
|
||||||
#undef _LZMA_LOC_OPT
|
#undef _LZMA_LOC_OPT
|
||||||
#endif
|
#endif
|
||||||
|
#if (ACC_ARCH_I086)
|
||||||
|
# define Byte unsigned char
|
||||||
|
# define _7ZIP_BYTE_DEFINED 1
|
||||||
|
#endif
|
||||||
|
#if !defined(_LZMA_UINT32_IS_ULONG)
|
||||||
|
# if defined(__INT_MAX__) && ((__INT_MAX__)+0 == 32767)
|
||||||
|
# define _LZMA_UINT32_IS_ULONG 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
@@ -51,10 +60,16 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 16)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define CLzmaDecoderState CLzmaDecoderState_dummy
|
#define CLzmaDecoderState CLzmaDecoderState_dummy
|
||||||
#define LzmaDecode LzmaDecode_dummy
|
#define LzmaDecodeProperties LzmaDecodeProperties_dummy
|
||||||
|
#define LzmaDecode LzmaDecode_dummy
|
||||||
|
#if (ACC_CC_BORLANDC)
|
||||||
|
#include "LzmaDecode.h"
|
||||||
|
#else
|
||||||
#include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
#include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
||||||
|
#endif
|
||||||
#undef CLzmaDecoderState
|
#undef CLzmaDecoderState
|
||||||
|
#undef LzmaDecodeProperties
|
||||||
#undef LzmaDecode
|
#undef LzmaDecode
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct { unsigned char lc, lp, pb, dummy; } Properties;
|
struct { unsigned char lc, lp, pb, dummy; } Properties;
|
||||||
@@ -64,10 +79,22 @@ typedef struct {
|
|||||||
CProb Probs[16382];
|
CProb Probs[16382];
|
||||||
#endif
|
#endif
|
||||||
} CLzmaDecoderState;
|
} CLzmaDecoderState;
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 32768)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 32768u)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(SizeT) >= 4)
|
||||||
|
|
||||||
|
#if (ACC_ARCH_I086)
|
||||||
|
# define char char __huge
|
||||||
|
#elif (ACC_CC_WATCOMC)
|
||||||
|
#else
|
||||||
#define CLzmaDecoderState const CLzmaDecoderState
|
#define CLzmaDecoderState const CLzmaDecoderState
|
||||||
|
#endif
|
||||||
|
#if (ACC_CC_BORLANDC)
|
||||||
|
#include "LzmaDecode.c"
|
||||||
|
#else
|
||||||
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||||
|
#endif
|
||||||
|
#undef char
|
||||||
|
#undef CLzmaDecoderState
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -59,15 +59,40 @@ strategy:
|
|||||||
push bp
|
push bp
|
||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
|
|
||||||
|
section LZMADEVICE
|
||||||
|
sub ax, offset exe_stack_ss + 0x10
|
||||||
|
mov ds, ax /* ds = cs - 0x10 */
|
||||||
|
|
||||||
|
section DEVICEENTRY2
|
||||||
.byte 0x72 /* "jc 0xf9" but flag C is 0 => nop */
|
.byte 0x72 /* "jc 0xf9" but flag C is 0 => nop */
|
||||||
exe_as_device_entry:
|
exe_as_device_entry:
|
||||||
stc /* flag C is 1 */
|
stc /* flag C is 1 */
|
||||||
pushf
|
pushf
|
||||||
|
|
||||||
|
/* ============= */
|
||||||
|
section LZMAENTRY
|
||||||
|
push ss
|
||||||
|
pop es
|
||||||
|
mov bx, 0x8000
|
||||||
|
xor cx, cx
|
||||||
|
mov si, offset COMPRESSED_LZMA_START + 0x100 /* ds = cs - 0x10 */
|
||||||
|
mov di, 0x10
|
||||||
|
mov bp, -1
|
||||||
|
.byte 0xa8 /* skips the following "movsb" */
|
||||||
|
|
||||||
|
#define COPY_MATCH .byte 0x26; rep movsb
|
||||||
|
#include "arch/i086/nrv2b_d16.S" /* for uncompressing lzma */
|
||||||
|
|
||||||
|
#define literal_n2b literal_n2b_
|
||||||
|
#define copy_match_n2b copy_match_n2b_
|
||||||
|
#define getbit_cx_n2b getbit_cx_n2b_
|
||||||
|
#define getbit_n2b getbit_n2b_
|
||||||
|
#define decomp_done_n2b decomp_done_n2b_
|
||||||
|
|
||||||
/* ============= */
|
/* ============= */
|
||||||
|
|
||||||
section EXEENTRY
|
section EXEENTRY
|
||||||
exe_entry:
|
|
||||||
mov cx, offset words_to_copy
|
mov cx, offset words_to_copy
|
||||||
mov si, offset copy_offset
|
mov si, offset copy_offset
|
||||||
mov di, si
|
mov di, si
|
||||||
@@ -86,11 +111,10 @@ addaxds:
|
|||||||
rep
|
rep
|
||||||
movsw
|
movsw
|
||||||
cld
|
cld
|
||||||
section DEVICESUB
|
section LONGSUB
|
||||||
/* subb [cs:si + addaxds + 4], 0x10 */
|
subb [cs:si + addaxds + 4], 0x10
|
||||||
|
section SHORTSUB
|
||||||
.byte 0x2e, 0x80, 0x6c, addaxds + 4, 0x10
|
.byte 0x2e, 0x80, 0x6c, addaxds + 4, 0x10
|
||||||
section EXESUB
|
|
||||||
subb [cs:si + addaxds - exe_entry + 4], 0x10
|
|
||||||
section JNCDOCOPY
|
section JNCDOCOPY
|
||||||
jncs do_copy
|
jncs do_copy
|
||||||
xchg ax, dx
|
xchg ax, dx
|
||||||
@@ -106,10 +130,14 @@ section EXEMAIN4
|
|||||||
pop es
|
pop es
|
||||||
push ss
|
push ss
|
||||||
mov bp, offset decompressor_entry
|
mov bp, offset decompressor_entry
|
||||||
|
section EXEMAIN4B
|
||||||
mov bx, offset bx_magic /* 0x800F + 0x10*bp - 0x10 */
|
mov bx, offset bx_magic /* 0x800F + 0x10*bp - 0x10 */
|
||||||
|
section EXEMAIN4C
|
||||||
push bp
|
push bp
|
||||||
lret
|
lret
|
||||||
|
|
||||||
|
section COMPRESSED_LZMA_START
|
||||||
|
|
||||||
#include "include/header.S"
|
#include "include/header.S"
|
||||||
|
|
||||||
section EXECUTPO
|
section EXECUTPO
|
||||||
@@ -117,6 +145,7 @@ section EXECUTPO
|
|||||||
#include "arch/i086/nrv2b_d8.S"
|
#include "arch/i086/nrv2b_d8.S"
|
||||||
#include "arch/i086/nrv2d_d8.S"
|
#include "arch/i086/nrv2d_d8.S"
|
||||||
#include "arch/i086/nrv2e_d8.S"
|
#include "arch/i086/nrv2e_d8.S"
|
||||||
|
#include "arch/i086/lzma_d.S"
|
||||||
|
|
||||||
section EXEMAIN5
|
section EXEMAIN5
|
||||||
pop bp
|
pop bp
|
||||||
@@ -217,6 +246,7 @@ section EXERETIP
|
|||||||
push ax
|
push ax
|
||||||
lret
|
lret
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=8:et:nowrap
|
vi:ts=8:et:nowrap
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ decompress:
|
|||||||
// // C callable decompressor
|
// // C callable decompressor
|
||||||
// **************************************************************************/
|
// **************************************************************************/
|
||||||
|
|
||||||
// /* Offsets to parameters, allowing for {push + pusha + call} */
|
// /* Offsets to parameters, allowing for {pusha + call} */
|
||||||
#define O_INP (4+ 8*4 +1*4)
|
#define O_INP (8*4 +1*4)
|
||||||
#define O_INS (4+ 8*4 +2*4)
|
#define O_INS (8*4 +2*4)
|
||||||
#define O_OUTP (4+ 8*4 +3*4)
|
#define O_OUTP (8*4 +3*4)
|
||||||
#define O_OUTS (4+ 8*4 +4*4)
|
#define O_OUTS (8*4 +4*4)
|
||||||
#define O_PARAM (4+ 8*4 +5*4)
|
#define O_PARAM (8*4 +5*4)
|
||||||
|
|
||||||
#define INP dword ptr [esp+O_INP]
|
#define INP dword ptr [esp+O_INP]
|
||||||
#define INS dword ptr [esp+O_INS]
|
#define INS dword ptr [esp+O_INS]
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
; i386-darwin.macho-entry.S -- program entry point & decompressor (i386 Mach-o)
|
||||||
|
;
|
||||||
|
; This file is part of the UPX executable compressor.
|
||||||
|
;
|
||||||
|
; Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
; Copyright (C) 1996-2007 Laszlo Molnar
|
||||||
|
; Copyright (C) 2000-2007 John F. Reiser
|
||||||
|
; All Rights Reserved.
|
||||||
|
;
|
||||||
|
; UPX and the UCL library are free software; you can redistribute them
|
||||||
|
; and/or modify them under the terms of the GNU General Public License as
|
||||||
|
; published by the Free Software Foundation; either version 2 of
|
||||||
|
; the License, or (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program; see the file COPYING.
|
||||||
|
; If not, write to the Free Software Foundation, Inc.,
|
||||||
|
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
;
|
||||||
|
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
;
|
||||||
|
; John F. Reiser
|
||||||
|
; <jreiser@users.sourceforge.net>
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/i386/macros.S"
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// program entry point
|
||||||
|
// see glibc/sysdeps/i386/elf/start.S
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
section LEXEC000
|
||||||
|
_start: .globl _start
|
||||||
|
//// int3
|
||||||
|
/*
|
||||||
|
;; How to debug this code: Uncomment the 'int3' breakpoint instruction above.
|
||||||
|
;; Build the stubs and upx. Compress a testcase, such as a copy of /bin/date.
|
||||||
|
;; Invoke gdb, and give a 'run' command. Define a single-step macro such as
|
||||||
|
;; define g
|
||||||
|
;; stepi
|
||||||
|
;; x/i $pc
|
||||||
|
;; end
|
||||||
|
;; and a step-over macro such as
|
||||||
|
;; define h
|
||||||
|
;; x/2i $pc
|
||||||
|
;; tbreak *$_
|
||||||
|
;; continue
|
||||||
|
;; x/i $pc
|
||||||
|
;; end
|
||||||
|
;; Step through the code; remember that <Enter> repeats the previous command.
|
||||||
|
;;
|
||||||
|
*/
|
||||||
|
call main // push address of decompress subroutine
|
||||||
|
decompress:
|
||||||
|
|
||||||
|
// /*************************************************************************
|
||||||
|
// // C callable decompressor
|
||||||
|
// **************************************************************************/
|
||||||
|
|
||||||
|
// /* Offsets to parameters, allowing for {pusha + call} */
|
||||||
|
#define O_INP (8*4 +1*4)
|
||||||
|
#define O_INS (8*4 +2*4)
|
||||||
|
#define O_OUTP (8*4 +3*4)
|
||||||
|
#define O_OUTS (8*4 +4*4)
|
||||||
|
#define O_PARAM (8*4 +5*4)
|
||||||
|
|
||||||
|
#define INP dword ptr [esp+O_INP]
|
||||||
|
#define INS dword ptr [esp+O_INS]
|
||||||
|
#define OUTP dword ptr [esp+O_OUTP]
|
||||||
|
#define OUTS dword ptr [esp+O_OUTS]
|
||||||
|
#define PARM dword ptr [esp+O_PARAM]
|
||||||
|
|
||||||
|
section LEXEC009
|
||||||
|
//; empty section for commonality with l_lx_exec86.asm
|
||||||
|
section LEXEC010
|
||||||
|
pusha
|
||||||
|
// cld
|
||||||
|
|
||||||
|
mov esi, INP
|
||||||
|
mov edi, OUTP
|
||||||
|
|
||||||
|
or ebp, -1
|
||||||
|
//;; align 8
|
||||||
|
|
||||||
|
#include "arch/i386/nrv2b_d32.S"
|
||||||
|
#include "arch/i386/nrv2d_d32.S"
|
||||||
|
#include "arch/i386/nrv2e_d32.S"
|
||||||
|
#include "arch/i386/lzma_d.S"
|
||||||
|
|
||||||
|
section LEXEC015
|
||||||
|
// eax is 0 from decompressor code
|
||||||
|
//xor eax, eax ; return code
|
||||||
|
|
||||||
|
// check compressed size
|
||||||
|
mov edx, INP
|
||||||
|
add edx, INS
|
||||||
|
cmp esi, edx
|
||||||
|
jz .ok
|
||||||
|
dec eax
|
||||||
|
.ok:
|
||||||
|
|
||||||
|
// write back the uncompressed size
|
||||||
|
sub edi, OUTP
|
||||||
|
mov edx, OUTS
|
||||||
|
mov [edx], edi
|
||||||
|
|
||||||
|
mov [7*4 + esp], eax
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
ctojr32
|
||||||
|
ctok32 edi, dl
|
||||||
|
cit32 edi
|
||||||
|
section LEXEC017
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
section LEXEC020
|
||||||
|
|
||||||
|
#define PAGE_SIZE ( 1<<12)
|
||||||
|
|
||||||
|
sz_b_info= 12
|
||||||
|
sz_unc= 0
|
||||||
|
sz_cpr= 4
|
||||||
|
b_method= 8
|
||||||
|
|
||||||
|
// Decompress the rest of this loader, and jump to it.
|
||||||
|
unfold:
|
||||||
|
pop esi // &{ b_info:{sz_unc, sz_cpr, 4{byte}}, compressed_data...}
|
||||||
|
mov eax,[sz_cpr + esi]
|
||||||
|
lea edx,[sz_b_info + eax + esi]
|
||||||
|
push edx // &destination
|
||||||
|
cld
|
||||||
|
lodsd
|
||||||
|
push eax // sz_uncompressed (maximum dstlen for lzma)
|
||||||
|
mov ecx,esp // save &dstlen
|
||||||
|
push eax // space for 5th param
|
||||||
|
push ecx // &dstlen
|
||||||
|
push edx // &dst
|
||||||
|
lodsd
|
||||||
|
push eax // sz_compressed (srclen)
|
||||||
|
lodsd
|
||||||
|
mov [4*3 + esp],eax // last 4 bytes of b_info
|
||||||
|
push esi // &compressed_data
|
||||||
|
call ebp // decompress(&src, srclen, &dst, &dstlen, b_info.misc)
|
||||||
|
add esp, (5+1)*4 // (5+1) args to decompress
|
||||||
|
ret // &destination
|
||||||
|
main:
|
||||||
|
pop ebp // &decompress
|
||||||
|
lea ebx,[-4+ _start - decompress + ebp] // &total_length
|
||||||
|
call unfold
|
||||||
|
// compressed fold_elf86 follows
|
||||||
|
|
||||||
|
// vi:ts=8:et:nowrap
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/* i386-darwin.macho-fold.S -- linkage to C code to process Mach-o binary
|
||||||
|
*
|
||||||
|
* This file is part of the UPX executable compressor.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
* Copyright (C) 1996-2007 Laszlo Molnar
|
||||||
|
* Copyright (C) 2000-2007 John F. Reiser
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* UPX and the UCL library are free software; you can redistribute them
|
||||||
|
* and/or modify them under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING.
|
||||||
|
* If not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
* <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* John F. Reiser
|
||||||
|
* <jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/i386/macros.S"
|
||||||
|
|
||||||
|
sz_b_info= 12
|
||||||
|
sz_unc= 0
|
||||||
|
sz_cpr= 4
|
||||||
|
|
||||||
|
sz_l_info= 12
|
||||||
|
sz_p_info= 12
|
||||||
|
|
||||||
|
_start: .globl _start # ignored, but silence "cannot find entry symbol _start" from ld
|
||||||
|
|
||||||
|
i386_ts_eax = 0*4
|
||||||
|
i386_ts_ebx = 1*4
|
||||||
|
i386_ts_ecx = 2*4
|
||||||
|
i386_ts_edx = 3*4
|
||||||
|
i386_ts_edi = 4*4
|
||||||
|
i386_ts_esi = 5*4
|
||||||
|
i386_ts_ebp = 6*4
|
||||||
|
i386_ts_esp = 7*4
|
||||||
|
i386_ts_ss = 8*4
|
||||||
|
i386_ts_eflags = 9*4
|
||||||
|
i386_ts_eip = 10*4
|
||||||
|
i386_ts_cs = 11*4
|
||||||
|
i386_ts_ds = 12*4
|
||||||
|
i386_ts_es = 13*4
|
||||||
|
i386_ts_fs = 14*4
|
||||||
|
i386_ts_gs = 15*4
|
||||||
|
|
||||||
|
fold_begin: // In: ebx= &total_length
|
||||||
|
//// int3
|
||||||
|
push 0 # default value for mhdrp
|
||||||
|
mov edi,esp # &mhdrp
|
||||||
|
lea esi,[ 2+ ebp] # &f_unfilter
|
||||||
|
mov edx,[ebx] # sz_total
|
||||||
|
mov ecx,ebx
|
||||||
|
sub ecx,edx # src= &{l_info; p_info; b_info}
|
||||||
|
mov ebx,[sz_unc + sz_p_info + sz_l_info + ecx] # sz_mach_headers
|
||||||
|
mov eax,2048 # allow for /usr/lib/dyld
|
||||||
|
cmp eax,ebx
|
||||||
|
jbe 0f
|
||||||
|
mov ebx,eax
|
||||||
|
0:
|
||||||
|
sub esp,ebx # alloca
|
||||||
|
pusha # (mhdrpp, f_unfilter, f_decompress, mhdr, sz_mhdr, sz_total, src, junk)
|
||||||
|
call upx_main # Out: eax= &Mach_i386_thread_state of dyld
|
||||||
|
mov ecx,[4*4 + esp] # sz_mhdr
|
||||||
|
lea esp,[8*4 + 1*ecx + esp] # un_pusha, un_alloca; keep mhdrp
|
||||||
|
jmp [i386_ts_eip + eax] # esp: mhdrp, argc, argv...
|
||||||
|
|
||||||
|
bswap: .globl bswap
|
||||||
|
mov eax,[4+ esp] # ptr
|
||||||
|
mov ecx,[8+ esp] # len
|
||||||
|
0:
|
||||||
|
mov edx,[eax]
|
||||||
|
.byte 0x0f,0xc8+2 // bswap edx
|
||||||
|
mov [eax],edx
|
||||||
|
sub ecx,4
|
||||||
|
lea eax,[4+ eax]
|
||||||
|
jae 0b
|
||||||
|
ret
|
||||||
|
|
||||||
|
SYS_exit =1
|
||||||
|
SYS_fork =2
|
||||||
|
SYS_read =3
|
||||||
|
SYS_write =4
|
||||||
|
SYS_open =5
|
||||||
|
SYS_close =6
|
||||||
|
|
||||||
|
SYS_pread =153
|
||||||
|
SYS_mmap =197
|
||||||
|
SYS_munmap = 73
|
||||||
|
SYS_mprotect= 74
|
||||||
|
|
||||||
|
sysgo:
|
||||||
|
pop edx # return address for sysenter
|
||||||
|
.byte 0x0f, 0x34 # sysenter
|
||||||
|
|
||||||
|
// lazy jmps enable compression of this code
|
||||||
|
exit: .globl exit
|
||||||
|
mov al,SYS_exit; jmps 2+ 0f; 0:
|
||||||
|
mprotect: .globl mprotect
|
||||||
|
mov al,SYS_mprotect; jmps 2+ 0f; 0:
|
||||||
|
munmap: .globl munmap
|
||||||
|
mov al,SYS_munmap; jmps 2+ 0f; 0:
|
||||||
|
pread: .globl pread
|
||||||
|
mov al,SYS_pread; jmps 2+ 0f; 0:
|
||||||
|
close: .globl close
|
||||||
|
mov al,SYS_close; jmps 2+ 0f; 0:
|
||||||
|
open: .globl open
|
||||||
|
mov al,SYS_open; jmps 2+ 0f; 0:
|
||||||
|
mmap: .globl mmap
|
||||||
|
mov al,SYS_mmap; jmps 2+ 0f; 0:
|
||||||
|
read: .globl read
|
||||||
|
mov al,SYS_read
|
||||||
|
|
||||||
|
movzbl eax,al # SYS_nnnnn
|
||||||
|
mov ecx,esp # &{user_ret_addr, arg1, arg2, ...}
|
||||||
|
call sysgo
|
||||||
|
jncs 0f
|
||||||
|
//mov errno,eax
|
||||||
|
or eax,~0
|
||||||
|
0:
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=8:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,460 @@
|
|||||||
|
/* i386-darwin.macho-main.c -- loader stub for Mach-o i386
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2007 Laszlo Molnar
|
||||||
|
Copyright (C) 2000-2007 John F. Reiser
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "include/darwin.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// configuration section
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// In order to make it much easier to move this code at runtime and execute
|
||||||
|
// it at an address different from it load address: there must be no
|
||||||
|
// static data, and no string constants.
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// "file" util
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t size; // must be first to match size[0] uncompressed size
|
||||||
|
char *buf;
|
||||||
|
} Extent;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
xread(Extent *x, char *buf, size_t count)
|
||||||
|
{
|
||||||
|
char *p=x->buf, *q=buf;
|
||||||
|
size_t j;
|
||||||
|
if (x->size < count) {
|
||||||
|
exit(127);
|
||||||
|
}
|
||||||
|
for (j = count; 0!=j--; ++p, ++q) {
|
||||||
|
*q = *p;
|
||||||
|
}
|
||||||
|
x->buf += count;
|
||||||
|
x->size -= count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// util
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if 1 //{ save space
|
||||||
|
#define ERR_LAB error: exit(127);
|
||||||
|
#define err_exit(a) goto error
|
||||||
|
#else //}{ save debugging time
|
||||||
|
#define ERR_LAB
|
||||||
|
static void
|
||||||
|
err_exit(int a)
|
||||||
|
{
|
||||||
|
(void)a; // debugging convenience
|
||||||
|
exit(127);
|
||||||
|
}
|
||||||
|
#endif //}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// UPX & NRV stuff
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
struct l_info { // 12-byte trailer for loader (after macho headers)
|
||||||
|
unsigned l_checksum;
|
||||||
|
unsigned l_magic; // UPX_MAGIC_LE32
|
||||||
|
unsigned short l_lsize;
|
||||||
|
unsigned char l_version;
|
||||||
|
unsigned char l_format;
|
||||||
|
};
|
||||||
|
struct p_info { // 12-byte packed program header
|
||||||
|
unsigned p_progid;
|
||||||
|
unsigned p_filesize;
|
||||||
|
unsigned p_blocksize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_info { // 12-byte header before each compressed block
|
||||||
|
unsigned sz_unc; // uncompressed_size
|
||||||
|
unsigned sz_cpr; // compressed_size
|
||||||
|
unsigned char b_method; // compression algorithm
|
||||||
|
unsigned char b_ftid; // filter id
|
||||||
|
unsigned char b_cto8; // filter parameter
|
||||||
|
unsigned char b_unused;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void f_unfilter(
|
||||||
|
nrv_byte *, // also addvalue
|
||||||
|
nrv_uint,
|
||||||
|
unsigned cto8, // junk in high 24 bits
|
||||||
|
unsigned ftid
|
||||||
|
);
|
||||||
|
typedef int f_expand(
|
||||||
|
const nrv_byte *, nrv_uint,
|
||||||
|
nrv_byte *, nrv_uint *, unsigned );
|
||||||
|
|
||||||
|
static void
|
||||||
|
unpackExtent(
|
||||||
|
Extent *const xi, // input
|
||||||
|
Extent *const xo, // output
|
||||||
|
f_expand *const f_decompress,
|
||||||
|
f_unfilter *f_unf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (xo->size) {
|
||||||
|
struct b_info h;
|
||||||
|
// Note: if h.sz_unc == h.sz_cpr then the block was not
|
||||||
|
// compressible and is stored in its uncompressed form.
|
||||||
|
|
||||||
|
// Read and check block sizes.
|
||||||
|
xread(xi, (char *)&h, sizeof(h));
|
||||||
|
if (h.sz_unc == 0) { // uncompressed size 0 -> EOF
|
||||||
|
if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic
|
||||||
|
err_exit(2);
|
||||||
|
if (xi->size != 0) // all bytes must be written
|
||||||
|
err_exit(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (h.sz_cpr <= 0) {
|
||||||
|
err_exit(4);
|
||||||
|
ERR_LAB
|
||||||
|
}
|
||||||
|
if (h.sz_cpr > h.sz_unc
|
||||||
|
|| h.sz_unc > xo->size ) {
|
||||||
|
err_exit(5);
|
||||||
|
}
|
||||||
|
// Now we have:
|
||||||
|
// assert(h.sz_cpr <= h.sz_unc);
|
||||||
|
// assert(h.sz_unc > 0 && h.sz_unc <= blocksize);
|
||||||
|
// assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize);
|
||||||
|
|
||||||
|
if (h.sz_cpr < h.sz_unc) { // Decompress block
|
||||||
|
nrv_uint out_len = h.sz_unc; // EOF for lzma
|
||||||
|
int const j = (*f_decompress)(xi->buf, h.sz_cpr,
|
||||||
|
xo->buf, &out_len, h.b_method);
|
||||||
|
if (j != 0 || out_len != (nrv_uint)h.sz_unc)
|
||||||
|
err_exit(7);
|
||||||
|
if (h.b_ftid!=0 && f_unf) { // have filter
|
||||||
|
(*f_unf)(xo->buf, out_len, h.b_cto8, h.b_ftid);
|
||||||
|
}
|
||||||
|
xi->buf += h.sz_cpr;
|
||||||
|
xi->size -= h.sz_cpr;
|
||||||
|
}
|
||||||
|
else { // copy literal block
|
||||||
|
xread(xi, xo->buf, h.sz_cpr);
|
||||||
|
}
|
||||||
|
xo->buf += h.sz_unc;
|
||||||
|
xo->size -= h.sz_unc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
upx_bzero(char *p, size_t len)
|
||||||
|
{
|
||||||
|
if (len) do {
|
||||||
|
*p++= 0;
|
||||||
|
} while (--len);
|
||||||
|
}
|
||||||
|
#define bzero upx_bzero
|
||||||
|
|
||||||
|
|
||||||
|
// The PF_* and PROT_* bits are {1,2,4}; the conversion table fits in 32 bits.
|
||||||
|
#define REP8(x) \
|
||||||
|
((x)|((x)<<4)|((x)<<8)|((x)<<12)|((x)<<16)|((x)<<20)|((x)<<24)|((x)<<28))
|
||||||
|
#define EXP8(y) \
|
||||||
|
((1&(y)) ? 0xf0f0f0f0 : (2&(y)) ? 0xff00ff00 : (4&(y)) ? 0xffff0000 : 0)
|
||||||
|
#define PF_TO_PROT(pf) \
|
||||||
|
((PROT_READ|PROT_WRITE|PROT_EXEC) & ( \
|
||||||
|
( (REP8(PROT_EXEC ) & EXP8(PF_X)) \
|
||||||
|
|(REP8(PROT_READ ) & EXP8(PF_R)) \
|
||||||
|
|(REP8(PROT_WRITE) & EXP8(PF_W)) \
|
||||||
|
) >> ((pf & (PF_R|PF_W|PF_X))<<2) ))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned magic;
|
||||||
|
unsigned nfat_arch;
|
||||||
|
} Fat_header;
|
||||||
|
typedef struct {
|
||||||
|
unsigned cputype;
|
||||||
|
unsigned cpusubtype;
|
||||||
|
unsigned offset;
|
||||||
|
unsigned size;
|
||||||
|
unsigned align; /* shift count; log base 2 */
|
||||||
|
} Fat_arch;
|
||||||
|
enum e8 {
|
||||||
|
FAT_MAGIC = 0xbebafeca // 0xcafebabe in big endian
|
||||||
|
};
|
||||||
|
enum e9 {
|
||||||
|
CPU_TYPE_I386 = 7,
|
||||||
|
CPU_TYPE_AMD64 = 0x01000007,
|
||||||
|
CPU_TYPE_POWERPC = 0x00000012,
|
||||||
|
CPU_TYPE_POWERPC64 = 0x01000012
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned magic;
|
||||||
|
unsigned cputype;
|
||||||
|
unsigned cpysubtype;
|
||||||
|
unsigned filetype;
|
||||||
|
unsigned ncmds;
|
||||||
|
unsigned sizeofcmds;
|
||||||
|
unsigned flags;
|
||||||
|
} Mach_header;
|
||||||
|
enum e0 {
|
||||||
|
MH_MAGIC = 0xfeedface
|
||||||
|
};
|
||||||
|
enum e2 {
|
||||||
|
MH_EXECUTE = 2
|
||||||
|
};
|
||||||
|
enum e3 {
|
||||||
|
MH_NOUNDEFS = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned cmd;
|
||||||
|
unsigned cmdsize;
|
||||||
|
} Mach_load_command;
|
||||||
|
enum e4 {
|
||||||
|
LC_SEGMENT = 0x1,
|
||||||
|
LC_THREAD = 0x4,
|
||||||
|
LC_UNIXTHREAD = 0x5,
|
||||||
|
LC_LOAD_DYLINKER = 0xe
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned cmd;
|
||||||
|
unsigned cmdsize;
|
||||||
|
char segname[16];
|
||||||
|
unsigned vmaddr;
|
||||||
|
unsigned vmsize;
|
||||||
|
unsigned fileoff;
|
||||||
|
unsigned filesize;
|
||||||
|
unsigned maxprot;
|
||||||
|
unsigned initprot;
|
||||||
|
unsigned nsects;
|
||||||
|
unsigned flags;
|
||||||
|
} Mach_segment_command;
|
||||||
|
enum e5 {
|
||||||
|
VM_PROT_READ = 1,
|
||||||
|
VM_PROT_WRITE = 2,
|
||||||
|
VM_PROT_EXECUTE = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned eax, ebx, ecx, edx;
|
||||||
|
unsigned edi, esi, ebp;
|
||||||
|
unsigned esp, ss;
|
||||||
|
unsigned eflags;
|
||||||
|
unsigned eip, cs;
|
||||||
|
unsigned ds, es, fs, gs;
|
||||||
|
} Mach_i386_thread_state;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||||
|
unsigned cmdsize; /* total size of this command */
|
||||||
|
unsigned flavor;
|
||||||
|
unsigned count; /* sizeof(following_thread_state)/4 */
|
||||||
|
Mach_i386_thread_state state;
|
||||||
|
} Mach_thread_command;
|
||||||
|
enum e6 {
|
||||||
|
i386_THREAD_STATE = 1
|
||||||
|
};
|
||||||
|
enum e7 {
|
||||||
|
i386_THREAD_STATE_COUNT = sizeof(Mach_i386_thread_state)/4
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
unsigned long offset; /* from start of load command to string */
|
||||||
|
char *ptr;
|
||||||
|
} Mach_lc_str;
|
||||||
|
|
||||||
|
#define MAP_FIXED 0x10
|
||||||
|
#define MAP_PRIVATE 0x02
|
||||||
|
#define MAP_ANON 0x1000
|
||||||
|
#define PROT_READ 1
|
||||||
|
#define PROT_WRITE 2
|
||||||
|
#define PROT_EXEC 4
|
||||||
|
|
||||||
|
typedef long long off_t;
|
||||||
|
extern char *mmap(char *, size_t, unsigned, unsigned, int, off_t);
|
||||||
|
extern ssize_t pread(int, void *, size_t, off_t);
|
||||||
|
extern void bswap(void *, unsigned);
|
||||||
|
|
||||||
|
static Mach_i386_thread_state const *
|
||||||
|
do_xmap(
|
||||||
|
Mach_header const *const mhdr,
|
||||||
|
unsigned const fat_offset,
|
||||||
|
Extent *const xi,
|
||||||
|
int const fdi,
|
||||||
|
Mach_header **mhdrpp,
|
||||||
|
f_expand *const f_decompress,
|
||||||
|
f_unfilter *const f_unf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr);
|
||||||
|
Mach_i386_thread_state const *entry = 0;
|
||||||
|
unsigned j;
|
||||||
|
|
||||||
|
for ( j=0; j < mhdr->ncmds; ++j,
|
||||||
|
(sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))
|
||||||
|
) if (LC_SEGMENT==sc->cmd) {
|
||||||
|
Extent xo;
|
||||||
|
size_t mlen = xo.size = sc->filesize;
|
||||||
|
char *addr = xo.buf = (char *)sc->vmaddr;
|
||||||
|
char *haddr = sc->vmsize + addr;
|
||||||
|
size_t frag = (int)addr &~ PAGE_MASK;
|
||||||
|
addr -= frag;
|
||||||
|
mlen += frag;
|
||||||
|
|
||||||
|
// Decompressor can overrun the destination by 3 bytes. [i386 only]
|
||||||
|
if (0!=mlen && addr != mmap(addr, mlen + (xi ? 3 : 0),
|
||||||
|
VM_PROT_READ | VM_PROT_WRITE,
|
||||||
|
MAP_FIXED | MAP_PRIVATE |
|
||||||
|
((xi || 0==sc->filesize) ? MAP_ANON : 0),
|
||||||
|
((0==sc->filesize) ? -1 : fdi), sc->fileoff + fat_offset) ) {
|
||||||
|
err_exit(8);
|
||||||
|
}
|
||||||
|
if (xi && 0!=sc->filesize) {
|
||||||
|
if (0==sc->fileoff && 0!=mhdrpp) {
|
||||||
|
*mhdrpp = (Mach_header *)addr;
|
||||||
|
}
|
||||||
|
unpackExtent(xi, &xo, f_decompress, f_unf);
|
||||||
|
}
|
||||||
|
/*bzero(addr, frag);*/ // fragment at lo end
|
||||||
|
frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary
|
||||||
|
bzero(mlen+addr, frag); // fragment at hi end
|
||||||
|
if (0!=mlen && 0!=mprotect(addr, mlen, sc->initprot)) {
|
||||||
|
err_exit(10);
|
||||||
|
ERR_LAB
|
||||||
|
}
|
||||||
|
addr += mlen + frag; /* page boundary on hi end */
|
||||||
|
if (addr < haddr) { // need pages for .bss
|
||||||
|
if (addr != mmap(addr, haddr - addr, sc->initprot,
|
||||||
|
MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0 ) ) {
|
||||||
|
err_exit(9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (xi) { // cleanup if decompressor overrun crosses page boundary
|
||||||
|
mlen = ~PAGE_MASK & (3+ mlen);
|
||||||
|
if (mlen<=3) { // page fragment was overrun buffer only
|
||||||
|
munmap(addr, mlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (LC_UNIXTHREAD==sc->cmd || LC_THREAD==sc->cmd) {
|
||||||
|
Mach_thread_command const *const thrc = (Mach_thread_command const *)sc;
|
||||||
|
if (i386_THREAD_STATE ==thrc->flavor
|
||||||
|
&& i386_THREAD_STATE_COUNT==thrc->count ) {
|
||||||
|
entry = &thrc->state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// upx_main - called by our entry code
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
Mach_i386_thread_state const *
|
||||||
|
upx_main(
|
||||||
|
Mach_header **const mhdrpp, // Out: *mhdrpp= &real Mach_header
|
||||||
|
f_unfilter *const f_unf,
|
||||||
|
f_expand *const f_decompress,
|
||||||
|
Mach_header *const mhdr, // temp char[sz_mhdr] for decompressing
|
||||||
|
size_t const sz_mhdr,
|
||||||
|
size_t volatile sz_compressed, // total length
|
||||||
|
struct l_info const *const li
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Mach_i386_thread_state const *entry;
|
||||||
|
unsigned fat_offset = 0;
|
||||||
|
Extent xi, xo, xi0;
|
||||||
|
xi.buf = CONST_CAST(char *, 1+ (struct p_info const *)(1+ li)); // &b_info
|
||||||
|
xi.size = sz_compressed - (sizeof(struct l_info) + sizeof(struct p_info));
|
||||||
|
xo.buf = (char *)mhdr;
|
||||||
|
xo.size = ((struct b_info const *)xi.buf)->sz_unc;
|
||||||
|
xi0 = xi;
|
||||||
|
|
||||||
|
// Uncompress Macho headers
|
||||||
|
unpackExtent(&xi, &xo, f_decompress, 0); // never filtered?
|
||||||
|
|
||||||
|
entry = do_xmap(mhdr, fat_offset, &xi0, -1, mhdrpp, f_decompress, f_unf);
|
||||||
|
|
||||||
|
{ // Map dyld dynamic loader
|
||||||
|
Mach_load_command const *lc = (Mach_load_command const *)(1+ mhdr);
|
||||||
|
unsigned j;
|
||||||
|
|
||||||
|
for (j=0; j < mhdr->ncmds; ++j,
|
||||||
|
(lc = (Mach_load_command const *)(lc->cmdsize + (char const *)lc))
|
||||||
|
) if (LC_LOAD_DYLINKER==lc->cmd) {
|
||||||
|
char const *const dyld_name = ((Mach_lc_str const *)(1+ lc))->offset +
|
||||||
|
(char const *)lc;
|
||||||
|
int const fdi = open(dyld_name, O_RDONLY, 0);
|
||||||
|
if (0 > fdi) {
|
||||||
|
err_exit(18);
|
||||||
|
}
|
||||||
|
fat:
|
||||||
|
if ((ssize_t)sz_mhdr!=pread(fdi, (void *)mhdr, sz_mhdr, fat_offset)) {
|
||||||
|
ERR_LAB
|
||||||
|
err_exit(19);
|
||||||
|
}
|
||||||
|
switch (mhdr->magic) {
|
||||||
|
case MH_MAGIC: break;
|
||||||
|
case FAT_MAGIC: {
|
||||||
|
// stupid Apple: waste code and a page fault on EVERY execve
|
||||||
|
Fat_header *const fh = (Fat_header *)mhdr;
|
||||||
|
Fat_arch *fa = (Fat_arch *)(1+ fh);
|
||||||
|
bswap(fh, sizeof(*fh) + (fh->nfat_arch>>24)*sizeof(*fa));
|
||||||
|
for (j= 0; j < fh->nfat_arch; ++j, ++fa) {
|
||||||
|
if (CPU_TYPE_I386==fa->cputype) {
|
||||||
|
fat_offset= fa->offset;
|
||||||
|
goto fat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
} // switch
|
||||||
|
entry = do_xmap(mhdr, fat_offset, 0, fdi, 0, 0, 0);
|
||||||
|
close(fdi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=4:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user