Compare commits

...

73 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer fc57390242 Bump release date. 2009-09-27 20:06:01 +02:00
Markus F.X.J. Oberhumer bd15ef0a0c Bump tentative 3.04 release date. 2009-09-21 05:44:19 +02:00
Markus F.X.J. Oberhumer 967ecafc33 Small compatibility updates. 2009-09-21 05:41:49 +02:00
John Reiser 29576da985 catch up to bugfix for arm-darwin stub 2009-09-01 07:33:08 -07:00
John Reiser 200a2556ef New format Mach/AMD64 for 64-bit x86 programs on Apple Macintosh 2009-09-01 07:30:37 -07:00
John Reiser ae0ab5025e fix debug mixup 2009-09-01 07:21:18 -07:00
John Reiser aa74276b25 gcc-4.4.1 is more strict about 'const' 2009-08-30 19:44:45 -07:00
Markus F.X.J. Oberhumer b03112a5dd Silence some compilation warnings. 2009-06-09 13:11:21 +02:00
Markus F.X.J. Oberhumer a3f49df62d Remove trailing whitespace. 2009-06-09 09:43:00 +02:00
Markus F.X.J. Oberhumer aa2af3f6dd Add missing stub to repo. 2009-06-09 09:40:25 +02:00
John Reiser 20dcbc593c PackMachFat for MH_DYLIB, too. 2009-06-01 16:23:13 -07:00
John Reiser 472ba8c1fd UPX_F_DYLIB_PPC32 is big endian, so move to >=128 2009-06-01 12:38:20 -07:00
John Reiser d8345a44a4 Dylib/ppc32 format works. 2009-05-31 12:57:10 -07:00
John Reiser a187cb6c9c work on stub for powerpc-darwin.dylib-entry.S 2009-05-29 22:08:08 -07:00
John Reiser b89c0b35d1 bugfix: PackMachBase::pack2 first extent is Mach_header plus Mach_segment_commands 2009-05-29 13:38:43 -07:00
John Reiser 7ffcc0a5e7 powerpc-darwin.dylib 2009-05-27 10:19:50 -07:00
John Reiser bde43fbdfb PackMachBase<T>::pack4dylib to prepare for more architectures 2009-05-23 21:13:44 -07:00
John Reiser 3728b2208f Cleanup declaration of PackDylibI386. 2009-05-22 08:37:44 -07:00
John Reiser dc52a756ee i386-darwin.dylib-entry.bin.dump 2009-05-21 22:06:26 -07:00
John Reiser 98dc886841 i386-darwin kernel expects 64-bit off_t; we always use 0 for top 32 bits. 2009-05-21 21:50:17 -07:00
John Reiser d0cf104e43 Announce Dylib/i386 format in NEWS. 2009-05-20 08:11:04 -07:00
John Reiser d7ed2412f6 386-darwin.dylib decompressor chains to user .init_address 2009-05-20 07:10:14 -07:00
John Reiser 7d38f0e234 i386-darwin.dylib ::unpack 2009-05-19 15:57:18 -07:00
John Reiser 3e8d072d24 i386-darwin.dylib requires existing LC_ROUINTES command;
decompressor must not overwrite Mach_headers.
2009-05-19 09:43:05 -07:00
John Reiser 84ac771893 Decompression part for Mach dylib i386. 2009-05-18 11:59:11 -07:00
John Reiser 3a9e0b5be6 Compression part for Mach dylib i386. 2009-05-13 10:40:21 -07:00
Markus F.X.J. Oberhumer 9694ff433f Fix grammar in version date. 2009-04-19 20:14:24 +02:00
Markus F.X.J. Oberhumer 2e82e78b98 Bump tentative release date. 2009-04-19 18:46:31 +02:00
Markus F.X.J. Oberhumer aaef4bee27 Prefer memcpy() over struct-copy. 2009-04-19 18:44:17 +02:00
Markus F.X.J. Oberhumer 4ca8569488 Remove trailing whitespace. 2009-04-19 18:36:42 +02:00
John Reiser 8377ada3e0 catch up stubs for arm 2009-03-01 11:19:05 -08:00
John Reiser 8a034d59ed arm linux kernel --small: hand assembly for LzmaDecode 2009-02-26 13:07:11 -08:00
John Reiser 8e492d8798 arm linux kernel: decompress_kernel() returns length, not pointer 2009-02-25 13:50:55 -08:00
John Reiser 7974ef80d7 branch merge 2009-02-12 12:42:57 -08:00
John Reiser 3664d86430 i386-linux.elf-fold fix compressed size for ET_DYN 2009-02-12 12:41:10 -08:00
Markus F.X.J. Oberhumer 9adef80d6b Replace all __attribute_packed by new __packed_struct macros. 2009-02-12 05:20:23 +01:00
Markus F.X.J. Oberhumer be57adaee7 Update tools/armpe_tester. 2009-02-12 03:33:14 +01:00
Markus F.X.J. Oberhumer d117e442a4 Silence a compiler warning. 2009-01-27 19:05:18 +01:00
Markus F.X.J. Oberhumer 8820bc0796 Add support for LZMA SDK 4.62. Compiles, but pretty much untested. 2009-01-03 23:33:25 +01:00
Markus F.X.J. Oberhumer 57a64de023 Small conf.h update. 2009-01-01 13:40:52 +01:00
Markus F.X.J. Oberhumer 5ed689ceb0 Enter 2009. 2008-12-31 17:07:18 +01:00
Markus F.X.J. Oberhumer 25f1765f36 Support building with OpenWatcom 1.8. Silence some compiler warnings. 2008-12-31 16:56:38 +01:00
Markus F.X.J. Oberhumer 063bd58802 Silence gcc's -Wstrict-aliasing=1 warnings. 2008-12-29 23:15:56 +01:00
Markus F.X.J. Oberhumer 901c6b34fa New ACC version. 2008-12-29 23:14:54 +01:00
Markus F.X.J. Oberhumer 5b2d6488a2 Silence some compilation warnings. 2008-12-29 22:22:28 +01:00
László Molnár f6f35415d1 check processor type in PackW32Pe::canUnpack 2008-12-20 14:48:13 +01:00
Markus F.X.J. Oberhumer 6c6069e963 New ACC version. 2008-12-16 23:59:37 +01:00
Markus F.X.J. Oberhumer 6219d82560 Detabified some sources. 2008-11-16 19:03:40 +01:00
John Reiser 1dcd7a16ab add missing source file 2008-11-16 08:01:40 -08:00
John Reiser b60caeb9dd source files for arm-darwin.macho-*.S 2008-11-16 07:35:53 -08:00
John Reiser 4c4768aaf3 derived .h fles for arm-darwin.macho 2008-11-15 14:46:03 -08:00
John Reiser 2f4ac0a663 format UPX_F_MACH_ARMEL, class PackMachARMEL: iPhone 2008-11-15 14:44:19 -08:00
John Reiser 23a446f852 unshare armel-linux.elf-main.o vs. arm-linux.elf-main.o (for comiler flags) 2008-11-15 14:09:06 -08:00
John Reiser ec48334a1a propagate changes into stub/amd64-linux.elf-fold.h 2008-11-15 08:52:02 -08:00
John Reiser f4c061d412 amd64-linux.elf: workaround for SIGSEGV on Centos 5.2
https://sourceforge.net/tracker/?func=detail&atid=102331&aid=2136491&group_id=2331
2008-11-15 08:49:13 -08:00
John Reiser 31a076d7b3 PackVmlinuzARMEL: only 8-bit control words for compression 2008-11-15 08:44:50 -08:00
John Reiser 6bd43d986c sync stub for armel-linux.kernel.vmlinuz.h 2008-09-15 13:51:55 -07:00
John Reiser dd32a2f15a forgot source for armel-linux.kernel.vmlinuz stubs 2008-09-15 10:35:53 -07:00
John Reiser c88c20820f new format vmlinuz/armel for Debian NSLU2 (etc.) linux kernel 2008-09-15 10:18:19 -07:00
John Reiser 86de510731 bvmlinuz boot protocol 2.08 (not yet complete?) 2008-08-04 17:30:44 -07:00
John Reiser 0b31fbf827 armel-eabi sets Elf32_Ehdr::EI_ABIVERSION = 4 2008-08-04 17:29:59 -07:00
John Reiser 34ad1450eb boot protocol 2.08 for bvmlinuz; Extended ABI version 4 for armel-eabi 2008-08-04 17:28:23 -07:00
John Reiser e6ba71390d armel-eabi choose proper decompressor 2008-07-20 15:35:19 -07:00
John Reiser f0c8dbe0ec armel-eabi-linux.elf (Debian) new protocol for system calls 2008-07-20 05:41:51 -07:00
John Reiser bf046a8ccb more checking when treating ELF as .bin 2008-07-20 05:40:00 -07:00
John Reiser b05ba7683e bvmlinuz/386 boot protocol 2.08 has gzipped ELF [needs more work] 2008-07-18 15:02:28 -07:00
John Reiser aedf8dad15 amd64 argc can be zero 2008-07-16 14:56:44 -07:00
John Reiser 74ebb7c722 more get_te32(&...) needed for endian neutrality 2008-07-16 13:49:28 -07:00
John Reiser 1307f66494 stub/i386-*.*-fold.S: allow 0==argc 2008-05-15 09:05:20 -07:00
John Reiser 448a24cb36 PackVmlinuzI386::getStrategy(), and Bvmlinuz guesses 60% .text;
stack for Bvmlinuz uses vacant Vmlinuz low memory (512 KiB)
2008-05-02 04:59:39 -07:00
Markus F.X.J. Oberhumer 7266f23450 New ACC version. 2008-04-30 02:45:13 +02:00
Markus F.X.J. Oberhumer c0ad31acfc Bump version for next release. 2008-04-27 18:46:52 +02:00
Markus F.X.J. Oberhumer 25d3a0de27 Added tag for RELEASE_303. 2008-04-27 11:38:15 +02:00
354 changed files with 21454 additions and 9347 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ stub/**.*-stamp
stub/tmp*/* stub/tmp*/*
stub/**/tmp*/* stub/**/tmp*/*
stub/tools/armpe/armpe_tester stub/tools/armpe/armpe_tester{,.exe,.out}
stub/tools/sstrip/amd64-linux-sstrip stub/tools/sstrip/amd64-linux-sstrip
stub/tools/sstrip/i386-linux-sstrip stub/tools/sstrip/i386-linux-sstrip
+1
View File
@@ -6,6 +6,7 @@
396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291 396983c065fc743cb5b9703e266ca87eeff8a6ee RELEASE_291
46f3a6cca02603000fadc16637b02e30caddd909 RELEASE_302 46f3a6cca02603000fadc16637b02e30caddd909 RELEASE_302
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200 70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
95c558f81a0b8d5bb2bede4c8208bb84ae7d1e58 RELEASE_303
a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292 a1c61174f54aac714f59ac20fcba839d71e64c5c RELEASE_292
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201 a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193 a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2008 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2009 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net http://upx.sourceforge.net
+2
View File
@@ -1,6 +1,8 @@
# #
# UPX toplevel Makefile - needs GNU make 3.81 or better # UPX toplevel Makefile - needs GNU make 3.81 or better
# #
# Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
#
MAKEFLAGS += -rR MAKEFLAGS += -rR
.SUFFIXES: .SUFFIXES:
+10
View File
@@ -2,6 +2,16 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
Changes in 3.04 (27 Sep 2009):
* new format Mach/AMD64 supports 64-bit programs on Apple Macintosh.
* new formats Dylib/i386 and Dylib/ppc32 support shared libraries
[such as browser plugins] on Darwin (Apple Macintosh). An existing
-init function (LC_ROUTINES command) is required.
* new format vmlinuz/armel for Debian NSLU2 (etc.) linux kernel
* bvmlinuz boot protocol 2.08 for 386 Linux kernel
* Extended ABI version 4 for armel-eabi ARM Linux ELF
* bug fixes
Changes in 3.03 (27 Apr 2008): Changes in 3.03 (27 Apr 2008):
* implement cache flushing for PowerPC (esp. model 440) * implement cache flushing for PowerPC (esp. model 440)
* fix cache flushing on MIPS (>3 MiB compressed, or with holes) * fix cache flushing on MIPS (>3 MiB compressed, or with holes)
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2008 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2009 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net http://upx.sourceforge.net
+4 -4
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2008 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2009 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net http://upx.sourceforge.net
@@ -108,9 +108,9 @@ THE FUTURE
COPYRIGHT COPYRIGHT
========= =========
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
This program may be used freely, and you are welcome to This program may be used freely, and you are welcome to
redistribute it under certain conditions. redistribute it under certain conditions.
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2008 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2009 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net http://upx.sourceforge.net
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2008 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2009 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net http://upx.sourceforge.net
+1 -1
View File
@@ -1,5 +1,5 @@
Decompressing ELF Directly to Memory on Linux/x86 Decompressing ELF Directly to Memory on Linux/x86
Copyright (C) 2000-2008 John F. Reiser jreiser@BitWagon.com Copyright (C) 2000-2009 John F. Reiser jreiser@BitWagon.com
References: References:
<elf.h> definitions for the ELF file format <elf.h> definitions for the ELF file format
+5 -5
View File
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
=head1 ABSTRACT =head1 ABSTRACT
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2008 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2009 Markus Oberhumer, Laszlo Molnar & John Reiser
http://upx.sourceforge.net http://upx.sourceforge.net
@@ -933,13 +933,13 @@ Please report all bugs immediately to the authors.
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
Copyright (C) 2002-2008 Jens Medoch Copyright (C) 2002-2009 Jens Medoch
This program may be used freely, and you are welcome to This program may be used freely, and you are welcome to
redistribute it under certain conditions. redistribute it under certain conditions.
+2
View File
@@ -1,6 +1,8 @@
# #
# UPX Makefile - needs GNU make 3.81 or better # UPX Makefile - needs GNU make 3.81 or better
# #
# Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
#
MAKEFLAGS += -rR MAKEFLAGS += -rR
.SUFFIXES: .SUFFIXES:
+18 -36
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -282,12 +282,12 @@ inline unsigned acc_swap32p(const acc_uint32e_t *p)
inline void acc_swab16s(acc_uint16e_t *p) inline void acc_swab16s(acc_uint16e_t *p)
{ {
*p = acc_swab16(*p); *p = (acc_uint16e_t) acc_swab16(*p);
} }
inline void acc_swab32s(acc_uint32e_t *p) inline void acc_swab32s(acc_uint32e_t *p)
{ {
*p = acc_swab32(*p); *p = (acc_uint32e_t) acc_swab32(*p);
} }
@@ -313,8 +313,7 @@ inline void acc_ua_swab32s(void *p)
// to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ] // to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
**************************************************************************/ **************************************************************************/
struct BE16 __packed_struct(BE16)
{
unsigned char d[2]; unsigned char d[2];
//inline BE16() { } //inline BE16() { }
@@ -332,12 +331,10 @@ struct BE16
BE16& operator >>= (unsigned v) { set_be16(d, get_be16(d) >> v); return *this; } BE16& operator >>= (unsigned v) { set_be16(d, get_be16(d) >> v); return *this; }
operator unsigned () const { return get_be16(d); } operator unsigned () const { return get_be16(d); }
} __packed_struct_end()
__attribute_packed;
struct BE32 __packed_struct(BE32)
{
unsigned char d[4]; unsigned char d[4];
//inline BE32() { } //inline BE32() { }
@@ -355,12 +352,10 @@ struct BE32
BE32& operator >>= (unsigned v) { set_be32(d, get_be32(d) >> v); return *this; } BE32& operator >>= (unsigned v) { set_be32(d, get_be32(d) >> v); return *this; }
operator unsigned () const { return get_be32(d); } operator unsigned () const { return get_be32(d); }
} __packed_struct_end()
__attribute_packed;
struct BE64 __packed_struct(BE64)
{
unsigned char d[8]; unsigned char d[8];
//inline BE64() { } //inline BE64() { }
@@ -378,12 +373,10 @@ struct BE64
BE64& operator >>= (unsigned v) { set_be64(d, get_be64(d) >> v); return *this; } BE64& operator >>= (unsigned v) { set_be64(d, get_be64(d) >> v); return *this; }
operator acc_uint64l_t () const { return get_be64(d); } operator acc_uint64l_t () const { return get_be64(d); }
} __packed_struct_end()
__attribute_packed;
struct LE16 __packed_struct(LE16)
{
unsigned char d[2]; unsigned char d[2];
//inline LE16() { } //inline LE16() { }
@@ -401,12 +394,10 @@ struct LE16
LE16& operator >>= (unsigned v) { set_le16(d, get_le16(d) >> v); return *this; } LE16& operator >>= (unsigned v) { set_le16(d, get_le16(d) >> v); return *this; }
operator unsigned () const { return get_le16(d); } operator unsigned () const { return get_le16(d); }
} __packed_struct_end()
__attribute_packed;
struct LE32 __packed_struct(LE32)
{
unsigned char d[4]; unsigned char d[4];
//inline LE32() { } //inline LE32() { }
@@ -424,12 +415,10 @@ struct LE32
LE32& operator >>= (unsigned v) { set_le32(d, get_le32(d) >> v); return *this; } LE32& operator >>= (unsigned v) { set_le32(d, get_le32(d) >> v); return *this; }
operator unsigned () const { return get_le32(d); } operator unsigned () const { return get_le32(d); }
} __packed_struct_end()
__attribute_packed;
struct LE64 __packed_struct(LE64)
{
unsigned char d[8]; unsigned char d[8];
//inline LE64() { } //inline LE64() { }
@@ -447,8 +436,7 @@ struct LE64
LE64& operator >>= (unsigned v) { set_le64(d, get_le64(d) >> v); return *this; } LE64& operator >>= (unsigned v) { set_le64(d, get_le64(d) >> v); return *this; }
operator acc_uint64l_t () const { return get_le64(d); } operator acc_uint64l_t () const { return get_le64(d); }
} __packed_struct_end()
__attribute_packed;
/************************************************************************* /*************************************************************************
@@ -623,16 +611,10 @@ namespace N_BELE_RTP {
} }
namespace N_BELE_CTP { namespace N_BELE_CTP {
inline const N_BELE_RTP::AbstractPolicy* getRTP(const BEPolicy*)
template <class T>
inline const N_BELE_RTP::AbstractPolicy* getRTP();
template <>
inline const N_BELE_RTP::AbstractPolicy* getRTP<BEPolicy>()
{ return &N_BELE_RTP::be_policy; } { return &N_BELE_RTP::be_policy; }
template <> inline const N_BELE_RTP::AbstractPolicy* getRTP(const LEPolicy*)
inline const N_BELE_RTP::AbstractPolicy* getRTP<LEPolicy>()
{ return &N_BELE_RTP::le_policy; } { return &N_BELE_RTP::le_policy; }
} }
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+357 -124
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -52,6 +52,8 @@ extern int compress_lzma_dummy;
int compress_lzma_dummy = 0; int compress_lzma_dummy = 0;
#else #else
#undef USE_LZMA_PROPERTIES
// INFO: the LZMA SDK is covered by a permissive license which allows // INFO: the LZMA SDK is covered by a permissive license which allows
// using unmodified LZMA source code in UPX and the UPX stubs. // using unmodified LZMA source code in UPX and the UPX stubs.
@@ -90,11 +92,244 @@ int compress_lzma_dummy = 0;
// while you keep LZMA SDK code unmodified. // while you keep LZMA SDK code unmodified.
#if (WITH_LZMA >= 0x461)
#include "C/7zVersion.h"
#if (WITH_LZMA != (0x100 * MY_VER_MAJOR) + (0x10 * (MY_VER_MINOR / 10)) + (MY_VER_MINOR % 10))
# error "WITH_LZMA version mismatch"
#endif
#include "C/Types.h"
static void *cb_alloc(void *, size_t size) {
return malloc(size);
}
static void cb_free(void *, void *ptr) {
free(ptr);
}
#endif
/************************************************************************* /*************************************************************************
// cruft because of pseudo-COM layer // compress defaults
**************************************************************************/ **************************************************************************/
#undef USE_LZMA_PROPERTIES static int prepare(lzma_compress_result_t *res,
unsigned src_len, int method, int level,
const lzma_compress_config_t *lcconf)
{
// setup defaults
res->pos_bits = 2; // 0 .. 4
res->lit_pos_bits = 0; // 0 .. 4
res->lit_context_bits = 3; // 0 .. 8
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
res->fast_mode = 2;
res->num_fast_bytes = 64; // 5 .. 273
res->match_finder_cycles = 0;
#if 1
res->pos_bits = lzma_compress_config_t::pos_bits_t::default_value_c;
res->lit_pos_bits = lzma_compress_config_t::lit_pos_bits_t::default_value_c;
res->lit_context_bits = lzma_compress_config_t::lit_context_bits_t::default_value_c;
res->dict_size = lzma_compress_config_t::dict_size_t::default_value_c;
res->num_fast_bytes = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
#endif
// method overrides
if (method >= 0x100) {
res->pos_bits = (method >> 16) & 15;
res->lit_pos_bits = (method >> 12) & 15;
res->lit_context_bits = (method >> 8) & 15;
}
#if 0
// DEBUG - set sizes so that we use a maxmimum amount of stack.
// These settings cause res->num_probs == 3147574, i.e. we will
// need about 6 MiB of stack during runtime decompression.
res->lit_pos_bits = 4;
res->lit_context_bits = 8;
#endif
// FIXME: tune these settings according to level
switch (level)
{
case 1:
res->dict_size = 256 * 1024;
res->fast_mode = 0;
res->num_fast_bytes = 8;
break;
case 2:
res->dict_size = 256 * 1024;
res->fast_mode = 0;
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
res->dict_size = 8 * 1024 * 1024;
break;
case 10:
res->dict_size = src_len;
break;
default:
goto error;
}
// cconf overrides
if (lcconf)
{
oassign(res->pos_bits, lcconf->pos_bits);
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
oassign(res->lit_context_bits, lcconf->lit_context_bits);
oassign(res->dict_size, lcconf->dict_size);
oassign(res->num_fast_bytes, lcconf->num_fast_bytes);
}
// limit dictionary size
if (res->dict_size > src_len)
res->dict_size = src_len;
// limit num_probs
if (lcconf && lcconf->max_num_probs)
{
for (;;)
{
unsigned n = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
if (n <= lcconf->max_num_probs)
break;
if (res->lit_pos_bits > res->lit_context_bits)
{
if (res->lit_pos_bits == 0)
goto error;
res->lit_pos_bits -= 1;
}
else
{
if (res->lit_context_bits == 0)
goto error;
res->lit_context_bits -= 1;
}
}
}
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
return 0;
error:
return -1;
}
/*************************************************************************
// compress
**************************************************************************/
#if (WITH_LZMA >= 0x461)
#define kLiteralNextStates kLiteralNextStates_enc
#include "C/LzmaEnc.h"
#include "C/LzmaEnc.c"
#include "C/LzFind.c"
#undef kLiteralNextStates
#undef kNumFullDistances
struct upx_ICompressProgress {
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
upx_callback_p cb;
};
static SRes cb_progress(void *p, UInt64 inSize, UInt64 outSize) {
upx_callback_p cb = ((upx_ICompressProgress *) p)->cb;
if (cb && cb->nprogress)
cb->nprogress(cb, (unsigned) inSize, (unsigned) outSize);
return SZ_OK;
}
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
int method, int level,
const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult )
{
assert(M_IS_LZMA(method));
assert(level > 0); assert(cresult != NULL);
COMPILE_TIME_ASSERT(LZMA_PROPS_SIZE == 5)
int r = UPX_E_ERROR;
int rh;
unsigned dst_avail = *dst_len;
*dst_len = 0;
ISzAlloc cba; cba.Alloc = cb_alloc; cba.Free = cb_free;
upx_ICompressProgress progress;
progress.Progress = cb_progress; progress.cb = cb;
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL;
lzma_compress_result_t *res = &cresult->result_lzma;
if (prepare(res, src_len, method, level, lcconf) != 0)
goto error;
CLzmaEncProps props; memset(&props, 0, sizeof(props));
props.level = level;
LzmaEncProps_Init(&props);
props.pb = res->pos_bits;
props.lp = res->lit_pos_bits;
props.lc = res->lit_context_bits;
props.dictSize = res->dict_size;
props.algo = res->fast_mode ? 1 : 0;
props.fb = res->num_fast_bytes;
props.mc = res->match_finder_cycles;
unsigned char props_buf[LZMA_PROPS_SIZE];
SizeT props_buf_size; props_buf_size = LZMA_PROPS_SIZE;
#if defined(USE_LZMA_PROPERTIES)
if (dst_avail < 1)
goto error;
dst[0] = 0; // filled below
dst += 1; *dst_len += 1; dst_avail -= 1;
#else
if (dst_avail < 2)
goto error;
// extra stuff in first byte: 5 high bits convenience for stub decompressor
unsigned tt; tt = res->lit_context_bits + res->lit_pos_bits;
dst[0] = ((tt << 3) | res->pos_bits);
dst[1] = ((res->lit_pos_bits << 4) | (res->lit_context_bits));
dst += 2; *dst_len += 2; dst_avail -= 2;
#endif
SizeT x_len; x_len = dst_avail;
rh = LzmaEncode(dst, &x_len, src, src_len,
&props, props_buf, &props_buf_size, 0,
(ICompressProgress *) (void *) &progress, &cba, &cba);
assert(x_len <= dst_avail);
*dst_len += x_len;
if (rh == SZ_OK) {
#if defined(USE_LZMA_PROPERTIES)
dst[-1] = probs_buf[0];
#endif
r = UPX_E_OK;
}
error:
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
return r;
}
#endif /* (WITH_LZMA >= 0x461) */
/*************************************************************************
// compress - cruft because of pseudo-COM layer
**************************************************************************/
#if (WITH_LZMA < 0x461)
#undef MSDOS #undef MSDOS
#undef OS2 #undef OS2
@@ -241,128 +476,25 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
NCoderPropID::kMatchFinder // 7 mf NCoderPropID::kMatchFinder // 7 mf
}; };
PROPVARIANT pr[8]; PROPVARIANT pr[8];
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
unsigned nprops = 7;
// setup defaults
pr[0].uintVal = 2; // 0 .. 4
pr[1].uintVal = 0; // 0 .. 4
pr[2].uintVal = 3; // 0 .. 8
pr[3].uintVal = 4 * 1024 * 1024; // 1 .. 2**30
pr[4].uintVal = 2;
pr[5].uintVal = 64; // 5 .. 273
pr[6].uintVal = 0;
#ifdef COMPRESS_MF_BT4 #ifdef COMPRESS_MF_BT4
const unsigned nprops = 8;
static wchar_t matchfinder[] = L"BT4"; static wchar_t matchfinder[] = L"BT4";
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0); assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
pr[nprops].vt = VT_BSTR; pr[7].vt = VT_BSTR; pr[7].bstrVal = matchfinder;
pr[nprops].bstrVal = matchfinder; #else
nprops++; const unsigned nprops = 7;
#endif #endif
#if 1 pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
pr[0].uintVal = lzma_compress_config_t::pos_bits_t::default_value_c; pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
pr[1].uintVal = lzma_compress_config_t::lit_pos_bits_t::default_value_c; if (prepare(res, src_len, method, level, lcconf) != 0)
pr[2].uintVal = lzma_compress_config_t::lit_context_bits_t::default_value_c;
pr[3].uintVal = lzma_compress_config_t::dict_size_t::default_value_c;
pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
#endif
// method overrides
if (method >= 0x100) {
pr[0].uintVal = (method >> 16) & 15;
pr[1].uintVal = (method >> 12) & 15;
pr[2].uintVal = (method >> 8) & 15;
}
#if 0
// DEBUG - set sizes so that we use a maxmimum amount of stack.
// These settings cause res->num_probs == 3147574, i.e. we will
// need about 6 MiB of stack during runtime decompression.
pr[1].uintVal = 4;
pr[2].uintVal = 8;
#endif
// FIXME: tune these settings according to level
switch (level)
{
case 1:
pr[3].uintVal = 256 * 1024;
pr[4].uintVal = 0;
pr[5].uintVal = 8;
break;
case 2:
pr[3].uintVal = 256 * 1024;
pr[4].uintVal = 0;
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
pr[3].uintVal = 8 * 1024 * 1024;
break;
case 10:
pr[3].uintVal = src_len;
break;
default:
goto error; goto error;
} pr[0].uintVal = res->pos_bits;
pr[1].uintVal = res->lit_pos_bits;
// cconf overrides pr[2].uintVal = res->lit_context_bits;
if (lcconf) pr[3].uintVal = res->dict_size;
{ pr[4].uintVal = res->fast_mode;
oassign(pr[0].uintVal, lcconf->pos_bits); pr[5].uintVal = res->num_fast_bytes;
oassign(pr[1].uintVal, lcconf->lit_pos_bits); pr[6].uintVal = res->match_finder_cycles;
oassign(pr[2].uintVal, lcconf->lit_context_bits);
oassign(pr[3].uintVal, lcconf->dict_size);
oassign(pr[5].uintVal, lcconf->num_fast_bytes);
}
// limit dictionary size
if (pr[3].uintVal > src_len)
pr[3].uintVal = src_len;
// limit num_probs
if (lcconf && lcconf->max_num_probs)
{
for (;;)
{
unsigned n = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
if (n <= lcconf->max_num_probs)
break;
if (pr[1].uintVal > pr[2].uintVal)
{
if (pr[1].uintVal == 0)
goto error;
pr[1].uintVal -= 1;
}
else
{
if (pr[2].uintVal == 0)
goto error;
pr[2].uintVal -= 1;
}
}
}
res->pos_bits = pr[0].uintVal;
res->lit_pos_bits = pr[1].uintVal;
res->lit_context_bits = pr[2].uintVal;
res->dict_size = pr[3].uintVal;
res->fast_mode = pr[4].uintVal;
res->num_fast_bytes = pr[5].uintVal;
res->match_finder_cycles = pr[6].uintVal;
//res->num_probs = LzmaGetNumProbs(&s.Properties));
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
#ifndef _NO_EXCEPTIONS #ifndef _NO_EXCEPTIONS
try { try {
@@ -419,11 +551,110 @@ error:
return r; return r;
} }
#endif /* (WITH_LZMA < 0x461) */
/************************************************************************* /*************************************************************************
// decompress // decompress
**************************************************************************/ **************************************************************************/
#if (WITH_LZMA >= 0x461)
#undef _LZMA_PROB32
#include "C/LzmaDec.h"
#include "C/LzmaDec.c"
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult )
{
#define Properties prop
assert(M_IS_LZMA(method));
// see res->num_probs above
COMPILE_TIME_ASSERT(sizeof(CLzmaProb) == 2)
COMPILE_TIME_ASSERT(LZMA_PROPS_SIZE == 5)
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
ISzAlloc cba; cba.Alloc = cb_alloc; cba.Free = cb_free;
CLzmaDec s; memset(&s, 0, sizeof(s));
SizeT srcLen = 0;
int r = UPX_E_ERROR;
SRes rh;
ELzmaStatus status;
#if defined(USE_LZMA_PROPERTIES)
rh = LzmaProps_Decode(&s.Properties, src, src_len);
if (rh != 0)
goto error;
src += 1; src_len -= 1;
#else
if (src_len < 3)
goto error;
s.Properties.pb = src[0] & 7;
s.Properties.lp = (src[1] >> 4);
s.Properties.lc = src[1] & 15;
if (s.Properties.pb >= 5) goto error;
if (s.Properties.lp >= 5) goto error;
if (s.Properties.lc >= 9) goto error;
// extra
if ((src[0] >> 3) != (int)(s.Properties.lc + s.Properties.lp)) goto error;
src += 2; src_len -= 2;
#endif
s.Properties.dicSize = 0;
if (cresult)
{
assert(cresult->method == method);
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
assert(cresult->result_lzma.num_probs == (unsigned) LzmaProps_GetNumProbs(&s.Properties));
const lzma_compress_result_t *res = &cresult->result_lzma;
UNUSED(res);
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
}
rh = LzmaDec_AllocateProbs2(&s, &s.Properties, &cba);
if (rh != SZ_OK)
{
r = UPX_E_OUT_OF_MEMORY;
goto error;
}
s.dic = dst; s.dicPos = 0; s.dicBufSize = *dst_len;
LzmaDec_Init(&s);
srcLen = src_len;
rh = LzmaDec_DecodeToDic(&s, *dst_len, src, &srcLen, LZMA_FINISH_ANY, &status);
assert(srcLen <= src_len);
assert(s.dicPos <= *dst_len);
if (rh == SZ_OK && status == LZMA_STATUS_NEEDS_MORE_INPUT)
rh = SZ_ERROR_INPUT_EOF;
if (rh == SZ_OK && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
{
r = UPX_E_OK;
if (srcLen != src_len)
r = UPX_E_INPUT_NOT_CONSUMED;
}
error:
*dst_len = s.dicPos;
// LzmaDec_Free(&s, &cba); // FIXME - why does this crash ???
return r;
#undef Properties
}
#endif /* (WITH_LZMA >= 0x461) */
/*************************************************************************
// decompress
**************************************************************************/
#if (WITH_LZMA < 0x461)
#undef _LZMA_IN_CB #undef _LZMA_IN_CB
#undef _LZMA_OUT_READ #undef _LZMA_OUT_READ
#undef _LZMA_PROB32 #undef _LZMA_PROB32
@@ -503,11 +734,11 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
error: error:
*dst_len = dst_out; *dst_len = dst_out;
free(s.Probs); free(s.Probs);
UNUSED(cresult);
return r; return r;
} }
#endif /* (WITH_LZMA < 0x461) */
/************************************************************************* /*************************************************************************
// test_overlap - see <ucl/ucl.h> for semantics // test_overlap - see <ucl/ucl.h> for semantics
@@ -545,7 +776,9 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
const char *upx_lzma_version_string(void) const char *upx_lzma_version_string(void)
{ {
#if (WITH_LZMA + 0 == 0x457) #if (WITH_LZMA >= 0x461)
return MY_VERSION;
#elif (WITH_LZMA + 0 == 0x457)
return "4.57"; return "4.57";
#elif (WITH_LZMA + 0 == 0x449) #elif (WITH_LZMA + 0 == 0x449)
return "4.49"; return "4.49";
+4 -4
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -85,7 +85,7 @@ static int convert_errno_from_ucl(int r)
extern "C" { extern "C" {
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
{ {
if (state != -1 && state != 3) return; if (state != -1 && state != 3) return;
upx_callback_p cb = (upx_callback_p) user; upx_callback_p cb = (upx_callback_p) user;
@@ -120,7 +120,7 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
ucl_compress_config_t cconf; cconf.reset(); ucl_compress_config_t cconf; cconf.reset();
if (cconf_parm) if (cconf_parm)
cconf = cconf_parm->conf_ucl; // struct copy memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf)); // cconf = cconf_parm->conf_ucl; // struct copy
ucl_uint *res = cresult->result_ucl.result; ucl_uint *res = cresult->result_ucl.result;
// assume no info available - fill in worst case results // assume no info available - fill in worst case results
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+34 -15
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -78,10 +78,13 @@
# if (ACC_OS_WIN32 || ACC_OS_WIN64) # if (ACC_OS_WIN32 || ACC_OS_WIN64)
# elif defined(__linux__) # elif defined(__linux__)
# pragma warning(error: 424) // #424: extra ";" ignored # pragma warning(error: 424) // #424: extra ";" ignored
//# pragma warning(disable: 128) // #128: loop is not reachable from preceding code
//# pragma warning(disable: 181) // #181: argument is incompatible with corresponding format string conversion
# pragma warning(disable: 193) // #193: zero used for undefined preprocessing identifier # pragma warning(disable: 193) // #193: zero used for undefined preprocessing identifier
# pragma warning(disable: 810) // #810: conversion from "A" to "B" may lose significant bits # pragma warning(disable: 810) // #810: conversion from "A" to "B" may lose significant bits
# pragma warning(disable: 981) // #981: operands are evaluated in unspecified order # pragma warning(disable: 981) // #981: operands are evaluated in unspecified order
# pragma warning(disable: 1418) // #1418: external definition with no prior declaration # pragma warning(disable: 1418) // #1418: external function definition with no prior declaration
//# pragma warning(disable: 1419) // #1419: external declaration in primary source file
# else # else
# error "untested platform" # error "untested platform"
# endif # endif
@@ -107,10 +110,13 @@
#elif (ACC_CC_SUNPROC) #elif (ACC_CC_SUNPROC)
//# pragma error_messages(off,"badargtype2w") // FIXME //# pragma error_messages(off,"badargtype2w") // FIXME
#elif (ACC_CC_WATCOMC) #elif (ACC_CC_WATCOMC)
# if (__WATCOMC__ < 1100) # if (__WATCOMC__ < 1280)
# error "need Watcom C++ 11.0c or newer" # error "need Open Watcom C++ 1.8 or newer" // because earlier versions do not support nested classes
# endif # endif
# if defined(__cplusplus) # if defined(__cplusplus)
# pragma warning 367 9 // w3: conditional expression in if statement is always true
# pragma warning 368 9 // w3: conditional expression in if statement is always false
# pragma warning 389 9 // w3: integral value may be truncated
# pragma warning 656 9 // w5: define this function inside its class definition (may improve code quality) # pragma warning 656 9 // w5: define this function inside its class definition (may improve code quality)
# endif # endif
#endif #endif
@@ -160,6 +166,9 @@
#if 0 && !defined(WITH_LZMA) #if 0 && !defined(WITH_LZMA)
# define WITH_LZMA 1 # define WITH_LZMA 1
#endif #endif
#if 1 && (ACC_CC_WATCOMC)
# undef WITH_LZMA
#endif
#if defined(UPX_OFFICIAL_BUILD) #if defined(UPX_OFFICIAL_BUILD)
# if !defined(WITH_LZMA) || !defined(WITH_NRV) || !defined(WITH_UCL) # if !defined(WITH_LZMA) || !defined(WITH_NRV) || !defined(WITH_UCL)
# error # error
@@ -301,16 +310,18 @@
#endif #endif
#undef __attribute_packed #if (ACC_CC_INTELC && (__INTEL_COMPILER < 800))
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE) #elif (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386))
# if (ACC_ARCH_I386) && (ACC_CC_INTELC && (__INTEL_COMPILER < 800)) #elif (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
# elif (0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386)) # define __packed_struct(s) struct s {
# else # define __packed_struct_end() } __attribute__((__packed__,__aligned__(1)));
# define __attribute_packed __attribute__((__packed__,__aligned__(1))) #elif (ACC_CC_WATCOMC)
# endif # define __packed_struct(s) _Packed struct s {
# define __packed_struct_end() };
#endif #endif
#if !defined(__attribute_packed) #if !defined(__packed_struct)
# define __attribute_packed # define __packed_struct(s) struct s {
# define __packed_struct_end() };
#endif #endif
@@ -323,8 +334,9 @@
#define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \ #define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \ typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
struct acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; } __attribute_packed; \ __packed_struct(acc_tmp_t) acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; __packed_struct_end() \
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \ COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t*)0)->x)+sizeof(((acc_tmp_t*)0)->y)+sizeof(((acc_tmp_t*)0)->z) == 2*sizeof(b)+sizeof(a)) \
} }
#if defined(__acc_alignof) #if defined(__acc_alignof)
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \ # define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
@@ -459,6 +471,12 @@ private:
#define UPX_F_VMLINUX_ARMEL 28 #define UPX_F_VMLINUX_ARMEL 28
#define UPX_F_MACH_i386 29 #define UPX_F_MACH_i386 29
#define UPX_F_LINUX_ELF32_MIPSEL 30 #define UPX_F_LINUX_ELF32_MIPSEL 30
#define UPX_F_VMLINUZ_ARMEL 31
#define UPX_F_MACH_ARMEL 32
#define UPX_F_DYLIB_i386 33
#define UPX_F_MACH_AMD64 34
#define UPX_F_DYLIB_AMD64 35
#define UPX_F_PLAIN_TEXT 127 #define UPX_F_PLAIN_TEXT 127
@@ -471,6 +489,7 @@ private:
#define UPX_F_VMLINUX_ARMEB 135 #define UPX_F_VMLINUX_ARMEB 135
#define UPX_F_VMLINUX_PPC32 136 #define UPX_F_VMLINUX_PPC32 136
#define UPX_F_LINUX_ELF32_MIPSEB 137 #define UPX_F_LINUX_ELF32_MIPSEB 137
#define UPX_F_DYLIB_PPC32 138
// compression methods // compression methods
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -366,6 +366,7 @@ off_t OutputFile::st_size() const
return bytes_written; // too big if seek()+write() instead of rewrite() return bytes_written; // too big if seek()+write() instead of rewrite()
} }
struct stat my_st; struct stat my_st;
my_st.st_size = 0;
if (::fstat(_fd, &my_st) != 0) if (::fstat(_fd, &my_st) != 0)
throwIOException(_name, errno); throwIOException(_name, errno);
return my_st.st_size; return my_st.st_size;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+11 -8
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2004-2008 John F. Reiser Copyright (C) 2004-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -47,7 +47,7 @@ static int F(Filter *f)
// scan // scan
const upx_byte *b = f->buf; const upx_byte *b = f->buf;
#endif #endif
const unsigned size = umin(f->buf_len, -(~0u<<(32 - (6+ W_CTO)))); const unsigned size = umin(f->buf_len, 0u - (~0u<<(32 - (6+ W_CTO))));
const unsigned size4 = size -4; const unsigned size4 = size -4;
unsigned ic; unsigned ic;
@@ -72,9 +72,11 @@ static int F(Filter *f)
} }
if (getcto(f, buf) < 0) { if (getcto(f, buf) < 0) {
if (0!=W_CTO) // FIXME: what is this ??? #if (W_CTO != 0)
return -1; return -1;
#else
f->cto = 0; f->cto = 0;
#endif
} }
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
@@ -95,8 +97,9 @@ static int F(Filter *f)
lastcall = ic; lastcall = ic;
} }
else { else {
assert(0==W_CTO // FIXME: what is this ??? #if (W_CTO != 0)
|| (~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != cto8); // this should not happen assert((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != cto8); // this should not happen
#endif
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@@ -122,7 +125,7 @@ static int F(Filter *f)
static int U(Filter *f) static int U(Filter *f)
{ {
upx_byte *b = f->buf; upx_byte *b = f->buf;
const unsigned size4 = umin(f->buf_len - 4, -(~0u<<(32 - (6+ W_CTO)))); const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u<<(32 - (6+ W_CTO))));
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
unsigned ic; unsigned ic;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+7 -7
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -51,7 +51,7 @@ void show_head(void)
fg = con_fg(f,FG_GREEN); fg = con_fg(f,FG_GREEN);
con_fprintf(f, con_fprintf(f,
" Ultimate Packer for eXecutables\n" " Ultimate Packer for eXecutables\n"
" Copyright (C) 1996 - 2008\n" " Copyright (C) 1996 - 2009\n"
"UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n", "UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
#if (ACC_OS_DOS16 || ACC_OS_DOS32) #if (ACC_OS_DOS16 || ACC_OS_DOS32)
V("d"), V("d"),
@@ -398,10 +398,10 @@ void show_version(int x)
if (v != NULL && v[0]) if (v != NULL && v[0])
fprintf(fp, "LZMA SDK version %s\n", v); fprintf(fp, "LZMA SDK version %s\n", v);
#endif #endif
fprintf(fp, "Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer\n"); fprintf(fp, "Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer\n");
fprintf(fp, "Copyright (C) 1996-2008 Laszlo Molnar\n"); fprintf(fp, "Copyright (C) 1996-2009 Laszlo Molnar\n");
fprintf(fp, "Copyright (C) 2000-2008 John F. Reiser\n"); fprintf(fp, "Copyright (C) 2000-2009 John F. Reiser\n");
fprintf(fp, "Copyright (C) 2002-2008 Jens Medoch\n"); fprintf(fp, "Copyright (C) 2002-2009 Jens Medoch\n");
#if defined(WITH_ZLIB) #if defined(WITH_ZLIB)
fprintf(fp, "Copyright (C) 1995" "-2005 Jean-loup Gailly and Mark Adler\n"); fprintf(fp, "Copyright (C) 1995" "-2005 Jean-loup Gailly and Mark Adler\n");
#endif #endif
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+9 -14
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -49,8 +49,8 @@ public:
protected: protected:
enum { FIXUP_EXTRA = 3 }; enum { FIXUP_EXTRA = 3 };
struct le_header_t __packed_struct(le_header_t)
{ // 0x00 // 0x00
char _[2]; // signature: 'LE' || 'LX' char _[2]; // signature: 'LE' || 'LX'
char byte_order; // 0 little endian char byte_order; // 0 little endian
char word_order; // 0 little endian char word_order; // 0 little endian
@@ -117,28 +117,23 @@ protected:
LE16 device_id; LE16 device_id;
LE16 ddk_version; LE16 ddk_version;
#endif #endif
} __packed_struct_end()
__attribute_packed;
struct le_object_table_entry_t __packed_struct(le_object_table_entry_t)
{
LE32 virtual_size; LE32 virtual_size;
LE32 base_address; LE32 base_address;
LE32 flags; LE32 flags;
LE32 pagemap_index; LE32 pagemap_index;
LE32 npages; LE32 npages;
LE32 reserved; LE32 reserved;
} __packed_struct_end()
__attribute_packed;
struct le_pagemap_entry_t __packed_struct(le_pagemap_entry_t)
{
unsigned char h; unsigned char h;
unsigned char m; unsigned char m;
unsigned char l; unsigned char l;
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
} __packed_struct_end()
__attribute_packed;
virtual void readObjectTable(); virtual void readObjectTable();
virtual void writeObjectTable(); virtual void writeObjectTable();
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+9 -5
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -1257,8 +1257,8 @@ template <class T> struct TestBELE {
static bool test(void) static bool test(void)
{ {
COMPILE_TIME_ASSERT_ALIGNED1(T) COMPILE_TIME_ASSERT_ALIGNED1(T)
struct test1_t { char a; T b; } __attribute_packed; __packed_struct(test1_t) char a; T b; __packed_struct_end()
struct test2_t { char a; T b[3]; } __attribute_packed; __packed_struct(test2_t) char a; T b[3]; __packed_struct_end()
test1_t t1[7]; UNUSED(t1); test2_t t2[7]; UNUSED(t2); test1_t t1[7]; UNUSED(t1); test2_t t2[7]; UNUSED(t2);
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T)) COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
COMPILE_TIME_ASSERT_ALIGNED1(test1_t) COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
@@ -1270,7 +1270,11 @@ static bool test(void)
COMPILE_TIME_ASSERT(__acc_alignof(t1) == 1) COMPILE_TIME_ASSERT(__acc_alignof(t1) == 1)
COMPILE_TIME_ASSERT(__acc_alignof(t2) == 1) COMPILE_TIME_ASSERT(__acc_alignof(t2) == 1)
#endif #endif
#if 1 && !defined(xUPX_OFFICIAL_BUILD) #if 1 && (ACC_CC_WATCOMC)
test1_t t11; COMPILE_TIME_ASSERT(sizeof(t11.a) <= sizeof(t11.b))
test2_t t22; COMPILE_TIME_ASSERT(sizeof(t22.a) <= sizeof(t22.b))
#endif
#if 1 && !defined(UPX_OFFICIAL_BUILD)
T allbits; allbits = 0; allbits -= 1; T allbits; allbits = 0; allbits -= 1;
//++allbits; allbits++; --allbits; allbits--; //++allbits; allbits++; --allbits; allbits--;
T v1; v1 = 1; v1 *= 2; v1 -= 1; T v1; v1 = 1; v1 *= 2; v1 -= 1;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+25 -13
View File
@@ -1,4 +1,4 @@
/* ACC -- Automatic Compiler Configuration /* ACC --- Automatic Compiler Configuration
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
@@ -39,7 +39,7 @@
#ifndef __ACC_H_INCLUDED #ifndef __ACC_H_INCLUDED
#define __ACC_H_INCLUDED 1 #define __ACC_H_INCLUDED 1
#define ACC_VERSION 20080102L #define ACC_VERSION 20081229L
#if defined(__CYGWIN32__) && !defined(__CYGWIN__) #if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__ # define __CYGWIN__ __CYGWIN32__
#endif #endif
@@ -577,6 +577,10 @@
# define ACC_CC_AZTECC 1 # define ACC_CC_AZTECC 1
# define ACC_INFO_CC "Aztec C" # define ACC_INFO_CC "Aztec C"
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__AZTEC_C__) # define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__AZTEC_C__)
#elif defined(__CODEGEARC__)
# define ACC_CC_CODEGEARC 1
# define ACC_INFO_CC "CodeGear C"
# define ACC_INFO_CCVER ACC_PP_MACRO_EXPAND(__CODEGEARC__)
#elif defined(__BORLANDC__) #elif defined(__BORLANDC__)
# define ACC_CC_BORLANDC 1 # define ACC_CC_BORLANDC 1
# define ACC_INFO_CC "Borland C" # define ACC_INFO_CC "Borland C"
@@ -1423,6 +1427,8 @@ extern "C" {
# define __acc_alignof(e) __alignof__(e) # define __acc_alignof(e) __alignof__(e)
#elif (ACC_CC_MSC && (_MSC_VER >= 1300)) #elif (ACC_CC_MSC && (_MSC_VER >= 1300))
# define __acc_alignof(e) __alignof(e) # define __acc_alignof(e) __alignof(e)
#elif (ACC_CC_SUNPROC && (ACC_CC_SUNPROC >= 0x5100))
# define __acc_alignof(e) __alignof__(e)
#endif #endif
#endif #endif
#if defined(__acc_alignof) #if defined(__acc_alignof)
@@ -1471,6 +1477,8 @@ extern "C" {
# define __acc_inline __inline # define __acc_inline __inline
#elif (ACC_CC_MSC && (_MSC_VER >= 900)) #elif (ACC_CC_MSC && (_MSC_VER >= 900))
# define __acc_inline __inline # define __acc_inline __inline
#elif (ACC_CC_SUNPROC && (ACC_CC_SUNPROC >= 0x5100))
# define __acc_inline __inline__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define __acc_inline inline # define __acc_inline inline
#endif #endif
@@ -1491,6 +1499,8 @@ extern "C" {
# define __acc_forceinline __inline__ __attribute__((__always_inline__)) # define __acc_forceinline __inline__ __attribute__((__always_inline__))
#elif (ACC_CC_MSC && (_MSC_VER >= 1200)) #elif (ACC_CC_MSC && (_MSC_VER >= 1200))
# define __acc_forceinline __forceinline # define __acc_forceinline __forceinline
#elif (ACC_CC_SUNPROC && (ACC_CC_SUNPROC >= 0x5100))
# define __acc_forceinline __inline__ __attribute__((__always_inline__))
#endif #endif
#endif #endif
#if defined(__acc_forceinline) #if defined(__acc_forceinline)
@@ -1516,6 +1526,8 @@ extern "C" {
# else # else
# define __acc_noinline __declspec(noinline) # define __acc_noinline __declspec(noinline)
# endif # endif
#elif (ACC_CC_SUNPROC && (ACC_CC_SUNPROC >= 0x5100))
# define __acc_noinline __attribute__((__noinline__))
#endif #endif
#endif #endif
#if defined(__acc_noinline) #if defined(__acc_noinline)
@@ -2187,7 +2199,7 @@ extern "C" {
#define HAVE_UMASK 1 #define HAVE_UMASK 1
#define HAVE_UTIME 1 #define HAVE_UTIME 1
#define HAVE_VSNPRINTF 1 #define HAVE_VSNPRINTF 1
#if (ACC_OS_BEOS || ACC_OS_CYGWIN || ACC_OS_POSIX || ACC_OS_QNX) #if (ACC_OS_BEOS || ACC_OS_CYGWIN || ACC_OS_POSIX || ACC_OS_QNX || ACC_OS_VMS)
# define HAVE_STRCASECMP 1 # define HAVE_STRCASECMP 1
# define HAVE_STRNCASECMP 1 # define HAVE_STRNCASECMP 1
#elif (ACC_OS_WIN32 && ACC_CC_GNUC) && defined(__PW32__) #elif (ACC_OS_WIN32 && ACC_CC_GNUC) && defined(__PW32__)
@@ -2624,7 +2636,7 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
# define acc_intptr_t acc_intptr_t # define acc_intptr_t acc_intptr_t
# define acc_uintptr_t acc_uintptr_t # define acc_uintptr_t acc_uintptr_t
# define ACC_SIZEOF_ACC_INTPTR_T ACC_SIZEOF_VOID_P # define ACC_SIZEOF_ACC_INTPTR_T ACC_SIZEOF_VOID_P
#elif (ACC_ARCH_I386 && ACC_CC_MSC && (_MSC_VER >= 1300)) #elif (ACC_CC_MSC && (_MSC_VER >= 1300) && (ACC_SIZEOF_VOID_P == 4) && (ACC_SIZEOF_INT == 4))
typedef __w64 int acc_intptr_t; typedef __w64 int acc_intptr_t;
typedef __w64 unsigned int acc_uintptr_t; typedef __w64 unsigned int acc_uintptr_t;
# define acc_intptr_t acc_intptr_t # define acc_intptr_t acc_intptr_t
@@ -2809,7 +2821,7 @@ typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#endif #endif
#if (ACC_OPT_UNALIGNED16) && defined(acc_int16e_t) #if (ACC_OPT_UNALIGNED16) && defined(acc_int16e_t)
#define ACC_UA_GET16(p) (* (__acc_ua_volatile const acc_uint16e_t*) (__acc_ua_volatile const void*) (p)) #define ACC_UA_GET16(p) (* (__acc_ua_volatile const acc_uint16e_t*) (__acc_ua_volatile const void*) (p))
#define ACC_UA_SET16(p,v) (* (__acc_ua_volatile acc_uint16e_t*) (__acc_ua_volatile void*) (p) = (acc_uint16e_t) (v)) #define ACC_UA_SET16(p,v) ((* (__acc_ua_volatile acc_uint16e_t*) (__acc_ua_volatile void*) (p)) = (acc_uint16e_t) (v))
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
# define ACC_UA_GET_BE16(p) ACC_UA_GET16(p) # define ACC_UA_GET_BE16(p) ACC_UA_GET16(p)
# define ACC_UA_SET_BE16(p,v) ACC_UA_SET16(p,v) # define ACC_UA_SET_BE16(p,v) ACC_UA_SET16(p,v)
@@ -2845,7 +2857,7 @@ extern __acc_forceinline void __ACC_UA_SET_LE16(__acc_ua_volatile void* pp, unsi
#endif #endif
#if (ACC_OPT_UNALIGNED32) && defined(acc_int32e_t) #if (ACC_OPT_UNALIGNED32) && defined(acc_int32e_t)
#define ACC_UA_GET32(p) (* (__acc_ua_volatile const acc_uint32e_t*) (__acc_ua_volatile const void*) (p)) #define ACC_UA_GET32(p) (* (__acc_ua_volatile const acc_uint32e_t*) (__acc_ua_volatile const void*) (p))
#define ACC_UA_SET32(p,v) (* (__acc_ua_volatile acc_uint32e_t*) (__acc_ua_volatile void*) (p) = (acc_uint32e_t) (v)) #define ACC_UA_SET32(p,v) ((* (__acc_ua_volatile acc_uint32e_t*) (__acc_ua_volatile void*) (p)) = (acc_uint32e_t) (v))
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
# define ACC_UA_GET_BE32(p) ACC_UA_GET32(p) # define ACC_UA_GET_BE32(p) ACC_UA_GET32(p)
# define ACC_UA_SET_BE32(p,v) ACC_UA_SET32(p,v) # define ACC_UA_SET_BE32(p,v) ACC_UA_SET32(p,v)
@@ -2881,7 +2893,7 @@ extern __acc_forceinline void __ACC_UA_SET_LE32(__acc_ua_volatile void* pp, unsi
#endif #endif
#if (ACC_OPT_UNALIGNED64) && defined(acc_int64l_t) #if (ACC_OPT_UNALIGNED64) && defined(acc_int64l_t)
#define ACC_UA_GET64(p) (* (__acc_ua_volatile const acc_uint64l_t*) (__acc_ua_volatile const void*) (p)) #define ACC_UA_GET64(p) (* (__acc_ua_volatile const acc_uint64l_t*) (__acc_ua_volatile const void*) (p))
#define ACC_UA_SET64(p,v) (* (__acc_ua_volatile acc_uint64l_t*) (__acc_ua_volatile void*) (p) = (acc_uint64l_t) (v)) #define ACC_UA_SET64(p,v) ((* (__acc_ua_volatile acc_uint64l_t*) (__acc_ua_volatile void*) (p)) = (acc_uint64l_t) (v))
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
# define ACC_UA_GET_BE64(p) ACC_UA_GET64(p) # define ACC_UA_GET_BE64(p) ACC_UA_GET64(p)
# define ACC_UA_SET_BE64(p,v) ACC_UA_SET64(p,v) # define ACC_UA_SET_BE64(p,v) ACC_UA_SET64(p,v)
@@ -3052,7 +3064,7 @@ __acc_gnuc_extension__ typedef unsigned long long acc_ullong_t;
# define acc_intptr_t acc_intptr_t # define acc_intptr_t acc_intptr_t
# define acc_uintptr_t acc_uintptr_t # define acc_uintptr_t acc_uintptr_t
# define ACC_SIZEOF_ACC_INTPTR_T ACC_SIZEOF_VOID_P # define ACC_SIZEOF_ACC_INTPTR_T ACC_SIZEOF_VOID_P
#elif (ACC_ARCH_I386 && ACC_CC_MSC && (_MSC_VER >= 1300)) #elif (ACC_CC_MSC && (_MSC_VER >= 1300) && (ACC_SIZEOF_VOID_P == 4) && (ACC_SIZEOF_INT == 4))
typedef __w64 int acc_intptr_t; typedef __w64 int acc_intptr_t;
typedef __w64 unsigned int acc_uintptr_t; typedef __w64 unsigned int acc_uintptr_t;
# define acc_intptr_t acc_intptr_t # define acc_intptr_t acc_intptr_t
@@ -3236,7 +3248,7 @@ typedef void (__acc_cdecl_sighandler *acc_sighandler_t)(acc_signo_t);
#endif #endif
#if (ACC_OPT_UNALIGNED16) && defined(acc_int16e_t) #if (ACC_OPT_UNALIGNED16) && defined(acc_int16e_t)
#define ACC_UA_GET16(p) (* (__acc_ua_volatile const acc_uint16e_t*) (__acc_ua_volatile const void*) (p)) #define ACC_UA_GET16(p) (* (__acc_ua_volatile const acc_uint16e_t*) (__acc_ua_volatile const void*) (p))
#define ACC_UA_SET16(p,v) (* (__acc_ua_volatile acc_uint16e_t*) (__acc_ua_volatile void*) (p) = (acc_uint16e_t) (v)) #define ACC_UA_SET16(p,v) ((* (__acc_ua_volatile acc_uint16e_t*) (__acc_ua_volatile void*) (p)) = (acc_uint16e_t) (v))
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
# define ACC_UA_GET_BE16(p) ACC_UA_GET16(p) # define ACC_UA_GET_BE16(p) ACC_UA_GET16(p)
# define ACC_UA_SET_BE16(p,v) ACC_UA_SET16(p,v) # define ACC_UA_SET_BE16(p,v) ACC_UA_SET16(p,v)
@@ -3272,7 +3284,7 @@ extern __acc_forceinline void __ACC_UA_SET_LE16(__acc_ua_volatile void* pp, unsi
#endif #endif
#if (ACC_OPT_UNALIGNED32) && defined(acc_int32e_t) #if (ACC_OPT_UNALIGNED32) && defined(acc_int32e_t)
#define ACC_UA_GET32(p) (* (__acc_ua_volatile const acc_uint32e_t*) (__acc_ua_volatile const void*) (p)) #define ACC_UA_GET32(p) (* (__acc_ua_volatile const acc_uint32e_t*) (__acc_ua_volatile const void*) (p))
#define ACC_UA_SET32(p,v) (* (__acc_ua_volatile acc_uint32e_t*) (__acc_ua_volatile void*) (p) = (acc_uint32e_t) (v)) #define ACC_UA_SET32(p,v) ((* (__acc_ua_volatile acc_uint32e_t*) (__acc_ua_volatile void*) (p)) = (acc_uint32e_t) (v))
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
# define ACC_UA_GET_BE32(p) ACC_UA_GET32(p) # define ACC_UA_GET_BE32(p) ACC_UA_GET32(p)
# define ACC_UA_SET_BE32(p,v) ACC_UA_SET32(p,v) # define ACC_UA_SET_BE32(p,v) ACC_UA_SET32(p,v)
@@ -3308,7 +3320,7 @@ extern __acc_forceinline void __ACC_UA_SET_LE32(__acc_ua_volatile void* pp, unsi
#endif #endif
#if (ACC_OPT_UNALIGNED64) && defined(acc_int64l_t) #if (ACC_OPT_UNALIGNED64) && defined(acc_int64l_t)
#define ACC_UA_GET64(p) (* (__acc_ua_volatile const acc_uint64l_t*) (__acc_ua_volatile const void*) (p)) #define ACC_UA_GET64(p) (* (__acc_ua_volatile const acc_uint64l_t*) (__acc_ua_volatile const void*) (p))
#define ACC_UA_SET64(p,v) (* (__acc_ua_volatile acc_uint64l_t*) (__acc_ua_volatile void*) (p) = (acc_uint64l_t) (v)) #define ACC_UA_SET64(p,v) ((* (__acc_ua_volatile acc_uint64l_t*) (__acc_ua_volatile void*) (p)) = (acc_uint64l_t) (v))
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
# define ACC_UA_GET_BE64(p) ACC_UA_GET64(p) # define ACC_UA_GET_BE64(p) ACC_UA_GET64(p)
# define ACC_UA_SET_BE64(p,v) ACC_UA_SET64(p,v) # define ACC_UA_SET_BE64(p,v) ACC_UA_SET64(p,v)
@@ -6418,11 +6430,11 @@ ACCLIB_PUBLIC_NOINLINE(void, acc_debug_nop) (void)
ACCLIB_PUBLIC_NOINLINE(int, acc_debug_align_check_query) (void) ACCLIB_PUBLIC_NOINLINE(int, acc_debug_align_check_query) (void)
{ {
#if (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_ASM_SYNTAX_GNUC) #if (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_ASM_SYNTAX_GNUC)
long r; size_t r;
__asm__ __volatile__("pushf\n pop %0\n" : "=a" (r) : : __ACC_ASM_CLOBBER); __asm__ __volatile__("pushf\n pop %0\n" : "=a" (r) : : __ACC_ASM_CLOBBER);
return (int)(r >> 18) & 1; return (int)(r >> 18) & 1;
#elif (ACC_ARCH_I386) && (ACC_ASM_SYNTAX_MSC) #elif (ACC_ARCH_I386) && (ACC_ASM_SYNTAX_MSC)
long r; unsigned long r;
__asm { __asm {
pushf pushf
pop eax pop eax
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+4 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -148,14 +148,12 @@ Linker* PackArmPe::newLinker() const
// import handling // import handling
**************************************************************************/ **************************************************************************/
struct import_desc __packed_struct(import_desc)
{
LE32 oft; // orig first thunk LE32 oft; // orig first thunk
char _[8]; char _[8];
LE32 dllname; LE32 dllname;
LE32 iat; // import address table LE32 iat; // import address table
} __packed_struct_end()
__attribute_packed;
void PackArmPe::processImports(unsigned myimport, unsigned iat_off) // pass 2 void PackArmPe::processImports(unsigned myimport, unsigned iat_off) // pass 2
{ {
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+6 -10
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -66,19 +66,16 @@ protected:
long coff_offset; long coff_offset;
struct external_scnhdr_t __packed_struct(external_scnhdr_t)
{
char _[12]; // name, paddr char _[12]; // name, paddr
LE32 vaddr; LE32 vaddr;
LE32 size; LE32 size;
LE32 scnptr; LE32 scnptr;
char misc[12]; // relptr, lnnoptr, nreloc, nlnno char misc[12]; // relptr, lnnoptr, nreloc, nlnno
char __[4]; // flags char __[4]; // flags
} __packed_struct_end()
__attribute_packed;
struct coff_header_t __packed_struct(coff_header_t)
{
// ext_file_hdr // ext_file_hdr
LE16 f_magic; LE16 f_magic;
LE16 f_nscns; LE16 f_nscns;
@@ -99,8 +96,7 @@ protected:
// section headers // section headers
external_scnhdr_t sh[3]; external_scnhdr_t sh[3];
} __packed_struct_end()
__attribute_packed;
coff_header_t coff_hdr; coff_header_t coff_hdr;
external_scnhdr_t *text,*data,*bss; external_scnhdr_t *text,*data,*bss;
+20 -38
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -52,8 +52,7 @@ struct ElfITypes
// The ELF file header. This appears at the start of every ELF file. // The ELF file header. This appears at the start of every ELF file.
template <class TElfITypes> template <class TElfITypes>
struct Ehdr __packed_struct(Ehdr)
{
typedef typename TElfITypes::Half Half; typedef typename TElfITypes::Half Half;
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -76,13 +75,11 @@ struct Ehdr
# define WANT_EHDR_ENUM 1 # define WANT_EHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TElfITypes> template <class TElfITypes>
struct Dyn __packed_struct(Dyn)
{
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -91,13 +88,11 @@ struct Dyn
# define WANT_DYN_ENUM 1 # define WANT_DYN_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TElfITypes> template <class TElfITypes>
struct External_Note __packed_struct(External_Note)
{
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
Word xn_namesz; // includes terminating '\0' Word xn_namesz; // includes terminating '\0'
@@ -105,8 +100,7 @@ struct External_Note
Word xn_type; Word xn_type;
//char xn_name[N]; // terminate with '\0' //char xn_name[N]; // terminate with '\0'
//char xn_data[M]; // aligned to 0 mod 4 //char xn_data[M]; // aligned to 0 mod 4
} __packed_struct_end()
__attribute_packed;
} // namespace N_Elf } // namespace N_Elf
@@ -119,8 +113,7 @@ __attribute_packed;
namespace N_Elf32 { namespace N_Elf32 {
template <class TElfITypes> template <class TElfITypes>
struct Phdr __packed_struct(Phdr)
{
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off; typedef typename TElfITypes::Off Off;
@@ -136,13 +129,11 @@ struct Phdr
# define WANT_PHDR_ENUM 1 # define WANT_PHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TElfITypes> template <class TElfITypes>
struct Shdr __packed_struct(Shdr)
{
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off; typedef typename TElfITypes::Off Off;
@@ -160,13 +151,11 @@ struct Shdr
# define WANT_SHDR_ENUM 1 # define WANT_SHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TElfITypes> template <class TElfITypes>
struct Sym __packed_struct(Sym)
{
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Section Section; typedef typename TElfITypes::Section Section;
@@ -184,8 +173,7 @@ struct Sym
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); } static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
static unsigned int get_st_type(unsigned x) { return 0xf & x ; } static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); } static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
} __packed_struct_end()
__attribute_packed;
} // namespace N_Elf32 } // namespace N_Elf32
@@ -198,8 +186,7 @@ __attribute_packed;
namespace N_Elf64 { namespace N_Elf64 {
template <class TElfITypes> template <class TElfITypes>
struct Phdr __packed_struct(Phdr)
{
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -216,13 +203,11 @@ struct Phdr
# define WANT_PHDR_ENUM 1 # define WANT_PHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TElfITypes> template <class TElfITypes>
struct Shdr __packed_struct(Shdr)
{
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -241,13 +226,11 @@ struct Shdr
# define WANT_SHDR_ENUM 1 # define WANT_SHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TElfITypes> template <class TElfITypes>
struct Sym __packed_struct(Sym)
{
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -266,8 +249,7 @@ struct Sym
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); } static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
static unsigned int get_st_type(unsigned x) { return 0xf & x ; } static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); } static unsigned char make_st_info(unsigned bind, unsigned type) { return (bind<<4) + (0xf & type); }
} __packed_struct_end()
__attribute_packed;
} // namespace N_Elf64 } // namespace N_Elf64
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+4 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -51,7 +51,8 @@ PackExe::PackExe(InputFile *f) :
super(f) super(f)
{ {
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32); COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32)
COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t)
ih_exesize = ih_imagesize = ih_overlay = 0; ih_exesize = ih_imagesize = ih_overlay = 0;
stack_for_lzma = 0; stack_for_lzma = 0;
use_clear_dirty_stack = false; use_clear_dirty_stack = false;
+4 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -74,8 +74,7 @@ protected:
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
void addLoaderEpilogue(int flag); void addLoaderEpilogue(int flag);
struct exe_header_t __packed_struct(exe_header_t)
{
LE16 ident; LE16 ident;
LE16 m512; LE16 m512;
LE16 p512; LE16 p512;
@@ -91,8 +90,7 @@ protected:
LE16 relocoffs; LE16 relocoffs;
char __[2]; // overlnum char __[2]; // overlnum
LE32 firstreloc; LE32 firstreloc;
} __packed_struct_end()
__attribute_packed;
exe_header_t ih, oh; exe_header_t ih, oh;
+86 -40
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -45,6 +45,8 @@
#define PT_LOAD32 Elf32_Phdr::PT_LOAD #define PT_LOAD32 Elf32_Phdr::PT_LOAD
#define PT_LOAD64 Elf64_Phdr::PT_LOAD #define PT_LOAD64 Elf64_Phdr::PT_LOAD
static unsigned const EF_ARM_HASENTRY = 0x02;
static unsigned const EF_ARM_EABI_VER4 = 0x04000000;
int int
PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const PackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const
@@ -720,6 +722,11 @@ PackOpenBSDElf32x86::buildLoader(const Filter *ft)
tmp, sizeof(stub_i386_openbsd_elf_fold), ft); tmp, sizeof(stub_i386_openbsd_elf_fold), ft);
} }
static const
#include "stub/armel-eabi-linux.elf-entry.h"
static const
#include "stub/armel-eabi-linux.elf-fold.h"
static const static const
#include "stub/arm-linux.elf-entry.h" #include "stub/arm-linux.elf-entry.h"
static const static const
@@ -743,9 +750,16 @@ PackLinuxElf32armBe::buildLoader(Filter const *ft)
void void
PackLinuxElf32armLe::buildLoader(Filter const *ft) PackLinuxElf32armLe::buildLoader(Filter const *ft)
{ {
if (Elf32_Ehdr::ELFOSABI_LINUX==ei_osabi) {
buildLinuxLoader(
stub_armel_eabi_linux_elf_entry, sizeof(stub_armel_eabi_linux_elf_entry),
stub_armel_eabi_linux_elf_fold, sizeof(stub_armel_eabi_linux_elf_fold), ft);
}
else {
buildLinuxLoader( buildLinuxLoader(
stub_arm_linux_elf_entry, sizeof(stub_arm_linux_elf_entry), stub_arm_linux_elf_entry, sizeof(stub_arm_linux_elf_entry),
stub_arm_linux_elf_fold, sizeof(stub_arm_linux_elf_fold), ft); stub_arm_linux_elf_fold, sizeof(stub_arm_linux_elf_fold), ft);
}
} }
static const static const
@@ -807,7 +821,7 @@ Elf32_Shdr const *PackLinuxElf32::elf_find_section_name(
Elf32_Shdr const *shdr = shdri; Elf32_Shdr const *shdr = shdri;
int j = n_elf_shnum; int j = n_elf_shnum;
for (; 0 <=--j; ++shdr) { for (; 0 <=--j; ++shdr) {
if (0==strcmp(name, &shstrtab[shdr->sh_name])) { if (0==strcmp(name, &shstrtab[get_te32(&shdr->sh_name)])) {
return shdr; return shdr;
} }
} }
@@ -821,7 +835,7 @@ Elf32_Shdr const *PackLinuxElf32::elf_find_section_type(
Elf32_Shdr const *shdr = shdri; Elf32_Shdr const *shdr = shdri;
int j = n_elf_shnum; int j = n_elf_shnum;
for (; 0 <=--j; ++shdr) { for (; 0 <=--j; ++shdr) {
if (type==shdr->sh_type) { if (type==get_te32(&shdr->sh_type)) {
return shdr; return shdr;
} }
} }
@@ -830,13 +844,16 @@ Elf32_Shdr const *PackLinuxElf32::elf_find_section_type(
bool PackLinuxElf32::canPack() bool PackLinuxElf32::canPack()
{ {
union {
unsigned char buf[sizeof(Elf32_Ehdr) + 14*sizeof(Elf32_Phdr)]; unsigned char buf[sizeof(Elf32_Ehdr) + 14*sizeof(Elf32_Phdr)];
COMPILE_TIME_ASSERT(sizeof(buf) <= 512); //struct { Elf32_Ehdr ehdr; Elf32_Phdr phdr; } e;
} u;
COMPILE_TIME_ASSERT(sizeof(u.buf) <= 512);
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(buf, sizeof(buf)); fi->readx(u.buf, sizeof(u.buf));
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf; Elf32_Ehdr const *const ehdr = (Elf32_Ehdr *) u.buf;
// now check the ELF header // now check the ELF header
if (checkEhdr(ehdr) != 0) if (checkEhdr(ehdr) != 0)
@@ -854,10 +871,10 @@ bool PackLinuxElf32::canPack()
return false; return false;
} }
unsigned osabi0 = buf[Elf32_Ehdr::EI_OSABI]; unsigned osabi0 = u.buf[Elf32_Ehdr::EI_OSABI];
// The first PT_LOAD32 must cover the beginning of the file (0==p_offset). // The first PT_LOAD32 must cover the beginning of the file (0==p_offset).
unsigned const e_phnum = get_te16(&ehdr->e_phnum); unsigned const e_phnum = get_te16(&ehdr->e_phnum);
Elf32_Phdr const *phdr = (Elf32_Phdr const *)(buf + e_phoff); Elf32_Phdr const *phdr = (Elf32_Phdr const *)(u.buf + e_phoff);
for (unsigned j=0; j < e_phnum; ++phdr, ++j) { for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (j >= 14) if (j >= 14)
return false; return false;
@@ -880,15 +897,23 @@ bool PackLinuxElf32::canPack()
&& 1==get_te32(&note.type) && 1==get_te32(&note.type)
&& 0==note.end && 0==note.end
&& (1+ strlen(osabi_note))==get_te32(&note.namesz) && (1+ strlen(osabi_note))==get_te32(&note.namesz)
&& 0==strcmp(osabi_note, (char const *)&note.text) && 0==strcmp(osabi_note, (char const *)note.text)
) { ) {
osabi0 = ei_osabi; // Specified by PT_NOTE. osabi0 = ei_osabi; // Specified by PT_NOTE.
} }
} }
} }
if (Elf32_Ehdr::ELFOSABI_NONE==osabi0) { // No EI_OSBAI, no PT_NOTE. if (Elf32_Ehdr::ELFOSABI_NONE==osabi0) { // No EI_OSBAI, no PT_NOTE.
if (Elf32_Ehdr::EM_ARM==e_machine
&& Elf32_Ehdr::ELFDATA2LSB==ei_data
&& EF_ARM_EABI_VER4==(0xff000000 & get_te32(&ehdr->e_flags))) {
// armel-eabi ARM little-endian Linux EABI version 4 is a mess.
ei_osabi = osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
}
else {
osabi0 = opt->o_unix.osabi0; // Possibly specified by command-line. osabi0 = opt->o_unix.osabi0; // Possibly specified by command-line.
} }
}
if (osabi0!=ei_osabi) { if (osabi0!=ei_osabi) {
return false; return false;
} }
@@ -912,7 +937,7 @@ bool PackLinuxElf32::canPack()
file_image = new char[file_size]; file_image = new char[file_size];
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(file_image, file_size); fi->readx(file_image, file_size);
ehdri= *ehdr; memcpy(&ehdri, ehdr, sizeof(Elf32_Ehdr));
phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !! phdri= (Elf32_Phdr *)(e_phoff + file_image); // do not free() !!
shdri= (Elf32_Shdr *)(e_shoff + file_image); // do not free() !! shdri= (Elf32_Shdr *)(e_shoff + file_image); // do not free() !!
@@ -980,12 +1005,15 @@ found:
bool bool
PackLinuxElf64amd::canPack() PackLinuxElf64amd::canPack()
{ {
union {
unsigned char buf[sizeof(Elf64_Ehdr) + 14*sizeof(Elf64_Phdr)]; unsigned char buf[sizeof(Elf64_Ehdr) + 14*sizeof(Elf64_Phdr)];
COMPILE_TIME_ASSERT(sizeof(buf) <= 1024); //struct { Elf64_Ehdr ehdr; Elf64_Phdr phdr; } e;
} u;
COMPILE_TIME_ASSERT(sizeof(u) <= 1024);
fi->readx(buf, sizeof(buf)); fi->readx(u.buf, sizeof(u.buf));
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
Elf64_Ehdr const *const ehdr = (Elf64_Ehdr const *)buf; Elf64_Ehdr const *const ehdr = (Elf64_Ehdr *) u.buf;
// now check the ELF header // now check the ELF header
if (checkEhdr(ehdr) != 0) if (checkEhdr(ehdr) != 0)
@@ -1004,7 +1032,7 @@ PackLinuxElf64amd::canPack()
// The first PT_LOAD64 must cover the beginning of the file (0==p_offset). // The first PT_LOAD64 must cover the beginning of the file (0==p_offset).
unsigned const e_phnum = get_te16(&ehdr->e_phnum); unsigned const e_phnum = get_te16(&ehdr->e_phnum);
Elf64_Phdr const *phdr = (Elf64_Phdr const *)(buf + (unsigned) e_phoff); Elf64_Phdr const *phdr = (Elf64_Phdr const *)(u.buf + (unsigned) e_phoff);
for (unsigned j=0; j < e_phnum; ++phdr, ++j) { for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (j >= 14) if (j >= 14)
return false; return false;
@@ -1049,9 +1077,10 @@ PackLinuxElf32::getbase(const Elf32_Phdr *phdr, int e_phnum) const
{ {
off_t base = ~0u; off_t base = ~0u;
for (int j = 0; j < e_phnum; ++phdr, ++j) { for (int j = 0; j < e_phnum; ++phdr, ++j) {
if (phdr->PT_LOAD == phdr->p_type) { if (phdr->PT_LOAD == get_te32(&phdr->p_type)) {
if (phdr->p_vaddr < (unsigned) base) unsigned const vaddr = get_te32(&phdr->p_vaddr);
base = phdr->p_vaddr; if (vaddr < (unsigned) base)
base = vaddr;
} }
} }
if (0!=base) { if (0!=base) {
@@ -1081,8 +1110,8 @@ PackLinuxElf32::generateElfHdr(
unsigned const brka unsigned const brka
) )
{ {
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout; cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout; cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi; h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;
if (Elf32_Ehdr::EM_MIPS==e_machine) { // MIPS R3000 FIXME if (Elf32_Ehdr::EM_MIPS==e_machine) { // MIPS R3000 FIXME
@@ -1209,8 +1238,8 @@ PackLinuxElf64::generateElfHdr(
unsigned const brka unsigned const brka
) )
{ {
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout; cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout; cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi; h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;
@@ -1297,7 +1326,15 @@ void PackLinuxElf32armLe::pack1(OutputFile *fo, Filter &ft)
{ {
super::pack1(fo, ft); super::pack1(fo, ft);
cprElfHdr3 h3; cprElfHdr3 h3;
if (Elf32_Ehdr::ELFOSABI_LINUX==ei_osabi) {
memcpy(&h3, stub_armel_eabi_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
set_te32(&h3.ehdr.e_flags, EF_ARM_EABI_VER4 | EF_ARM_HASENTRY);
h3.ehdr.e_ident[Elf32_Ehdr::EI_ABIVERSION] = 4;
}
else {
memcpy(&h3, stub_arm_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr)); memcpy(&h3, stub_arm_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
}
generateElfHdr(fo, &h3, getbrk(phdri, get_te16(&ehdri.e_phnum)) ); generateElfHdr(fo, &h3, getbrk(phdri, get_te16(&ehdri.e_phnum)) );
} }
@@ -1857,14 +1894,17 @@ void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft)
void PackLinuxElf32::unpack(OutputFile *fo) void PackLinuxElf32::unpack(OutputFile *fo)
{ {
#define MAX_ELF_HDR 512 #define MAX_ELF_HDR 512
char bufehdr[MAX_ELF_HDR]; union {
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)bufehdr; unsigned char buf[MAX_ELF_HDR];
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ehdr); //struct { Elf32_Ehdr ehdr; Elf32_Phdr phdr; } e;
} u;
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *) u.buf;
Elf32_Phdr const *phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
unsigned szb_info = sizeof(b_info); unsigned szb_info = sizeof(b_info);
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(bufehdr, MAX_ELF_HDR); fi->readx(u.buf, MAX_ELF_HDR);
unsigned const e_entry = get_te32(&ehdr->e_entry); unsigned const e_entry = get_te32(&ehdr->e_entry);
if (e_entry < 0x401180 if (e_entry < 0x401180
&& ehdr->e_machine==Elf32_Ehdr::EM_386) { /* old style, 8-byte b_info */ && ehdr->e_machine==Elf32_Ehdr::EM_386) { /* old style, 8-byte b_info */
@@ -1918,7 +1958,7 @@ void PackLinuxElf32::unpack(OutputFile *fo)
} }
} }
phdr = (Elf32_Phdr *)(1+ehdr); phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
for (unsigned j = 0; j < phnum; ++j) { for (unsigned j = 0; j < phnum; ++j) {
unsigned const size = find_LOAD_gap(phdr, j, phnum); unsigned const size = find_LOAD_gap(phdr, j, phnum);
if (size) { if (size) {
@@ -1962,14 +2002,17 @@ void PackLinuxElf32::unpack(OutputFile *fo)
void PackLinuxElf64::unpack(OutputFile *fo) void PackLinuxElf64::unpack(OutputFile *fo)
{ {
#define MAX_ELF_HDR 1024 #define MAX_ELF_HDR 1024
char bufehdr[MAX_ELF_HDR]; union {
Elf64_Ehdr *const ehdr = (Elf64_Ehdr *)bufehdr; unsigned char buf[MAX_ELF_HDR];
Elf64_Phdr const *phdr = (Elf64_Phdr *)(1+ehdr); //struct { Elf64_Ehdr ehdr; Elf64_Phdr phdr; } e;
} u;
Elf64_Ehdr *const ehdr = (Elf64_Ehdr *) u.buf;
Elf64_Phdr const *phdr = (Elf64_Phdr *) (u.buf + sizeof(*ehdr));
unsigned szb_info = sizeof(b_info); unsigned szb_info = sizeof(b_info);
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(bufehdr, MAX_ELF_HDR); fi->readx(u.buf, MAX_ELF_HDR);
acc_uint64l_t const e_entry = get_te64(&ehdr->e_entry); acc_uint64l_t const e_entry = get_te64(&ehdr->e_entry);
if (e_entry < 0x401180 if (e_entry < 0x401180
&& ehdr->e_machine==Elf64_Ehdr::EM_386) { /* old style, 8-byte b_info */ && ehdr->e_machine==Elf64_Ehdr::EM_386) { /* old style, 8-byte b_info */
@@ -2023,7 +2066,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
} }
} }
phdr = (Elf64_Phdr *)(1+ehdr); phdr = (Elf64_Phdr *) (u.buf + sizeof(*ehdr));
for (unsigned j = 0; j < phnum; ++j) { for (unsigned j = 0; j < phnum; ++j) {
unsigned const size = find_LOAD_gap(phdr, j, phnum); unsigned const size = find_LOAD_gap(phdr, j, phnum);
if (size) { if (size) {
@@ -2280,7 +2323,7 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
unsigned const m = elf_hash(name) % nbucket; unsigned const m = elf_hash(name) % nbucket;
unsigned si; unsigned si;
for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) { for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) {
char const *const p= dynsym[si].st_name + dynstr; char const *const p= get_te32(&dynsym[si].st_name) + dynstr;
if (0==strcmp(name, p)) { if (0==strcmp(name, p)) {
return &dynsym[si]; return &dynsym[si];
} }
@@ -2308,7 +2351,7 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
dsp += bucket; dsp += bucket;
do if (0==((h ^ get_te32(hp))>>1)) { do if (0==((h ^ get_te32(hp))>>1)) {
char const *const p = dsp->st_name + dynstr; char const *const p = get_te32(&dsp->st_name) + dynstr;
if (0==strcmp(name, p)) { if (0==strcmp(name, p)) {
return dsp; return dsp;
} }
@@ -2323,14 +2366,17 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const
void PackLinuxElf32x86::unpack(OutputFile *fo) void PackLinuxElf32x86::unpack(OutputFile *fo)
{ {
#define MAX_ELF_HDR 512 #define MAX_ELF_HDR 512
char bufehdr[MAX_ELF_HDR]; union {
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)bufehdr; unsigned char buf[MAX_ELF_HDR];
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ehdr); //struct { Elf32_Ehdr ehdr; Elf32_Phdr phdr; } e;
} u;
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *) u.buf;
Elf32_Phdr const *phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
unsigned szb_info = sizeof(b_info); unsigned szb_info = sizeof(b_info);
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(bufehdr, MAX_ELF_HDR); fi->readx(u.buf, MAX_ELF_HDR);
unsigned const e_entry = get_te32(&ehdr->e_entry); unsigned const e_entry = get_te32(&ehdr->e_entry);
unsigned const e_type = get_te16(&ehdr->e_type); unsigned const e_type = get_te16(&ehdr->e_type);
if (e_entry < 0x401180 && Elf32_Ehdr::ET_EXEC==e_type) { if (e_entry < 0x401180 && Elf32_Ehdr::ET_EXEC==e_type) {
@@ -2384,7 +2430,7 @@ void PackLinuxElf32x86::unpack(OutputFile *fo)
} }
} }
phdr = (Elf32_Phdr *)(1+ehdr); phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
for (unsigned j = 0; j < phnum; ++j) { for (unsigned j = 0; j < phnum; ++j) {
unsigned const size = find_LOAD_gap(phdr, j, phnum); unsigned const size = find_LOAD_gap(phdr, j, phnum);
if (size) { if (size) {
+15 -21
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -145,26 +145,23 @@ protected:
Elf32_Shdr const *sec_dynsym; Elf32_Shdr const *sec_dynsym;
Elf32_Shdr const *sec_dynstr; Elf32_Shdr const *sec_dynstr;
struct cprElfHdr1 { __packed_struct(cprElfHdr1)
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[1]; Elf32_Phdr phdr[1];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
struct cprElfHdr2 { __packed_struct(cprElfHdr2)
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[2]; Elf32_Phdr phdr[2];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
struct cprElfHdr3 { __packed_struct(cprElfHdr3)
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[3]; Elf32_Phdr phdr[3];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
cprElfHdr3 elfout; cprElfHdr3 elfout;
@@ -227,26 +224,23 @@ protected:
Elf64_Phdr *phdri; // for input file Elf64_Phdr *phdri; // for input file
acc_uint64l_t page_mask; // AND clears the offset-within-page acc_uint64l_t page_mask; // AND clears the offset-within-page
struct cprElfHdr1 { __packed_struct(cprElfHdr1)
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Phdr phdr[1]; Elf64_Phdr phdr[1];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
struct cprElfHdr2 { __packed_struct(cprElfHdr2)
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Phdr phdr[2]; Elf64_Phdr phdr[2];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
struct cprElfHdr3 { __packed_struct(cprElfHdr3)
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Phdr phdr[3]; Elf64_Phdr phdr[3];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
cprElfHdr3 elfout; cprElfHdr3 elfout;
+13 -10
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2001-2008 John F. Reiser Copyright (C) 2001-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -132,8 +132,8 @@ PackLinuxI386::generateElfHdr(
unsigned const brka unsigned const brka
) )
{ {
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout; cprElfHdr2 *const h2 = (cprElfHdr2 *)(void *)&elfout;
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout; cprElfHdr3 *const h3 = (cprElfHdr3 *)(void *)&elfout;
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
assert(h2->ehdr.e_phoff == sizeof(Elf32_Ehdr)); assert(h2->ehdr.e_phoff == sizeof(Elf32_Ehdr));
@@ -528,11 +528,14 @@ bool PackLinuxI386::canPack()
default: default:
unsigned const e_phnum = get_te16(&ehdr.e_phnum); unsigned const e_phnum = get_te16(&ehdr.e_phnum);
if (e_phnum<=(512/sizeof(Elf32_Phdr))) { if (e_phnum<=(512/sizeof(Elf32_Phdr))) {
char buf2[512]; union {
unsigned char buf2[512];
//Elf32_Phdr phdr;
} u;
fi->seek(get_te32(&ehdr.e_phoff), SEEK_SET); fi->seek(get_te32(&ehdr.e_phoff), SEEK_SET);
fi->readx(buf2, sizeof(buf2)); fi->readx(u.buf2, sizeof(u.buf2));
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
Elf32_Phdr const *phdr = (Elf32_Phdr const *)buf2; Elf32_Phdr const *phdr = (Elf32_Phdr *) u.buf2;
for (unsigned j=0; j < e_phnum; ++phdr, ++j) { for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (phdr->PT_NOTE == get_te32(&phdr->p_type)) { if (phdr->PT_NOTE == get_te32(&phdr->p_type)) {
unsigned const offset = get_te32(&phdr->p_offset); unsigned const offset = get_te32(&phdr->p_offset);
@@ -543,11 +546,11 @@ bool PackLinuxI386::canPack()
if (4==get_te32(&note.descsz) if (4==get_te32(&note.descsz)
&& 1==get_te32(&note.type) && 1==get_te32(&note.type)
&& 0==note.end ) { && 0==note.end ) {
if (0==strcmp("NetBSD", (char const *)&note.text)) { if (0==strcmp("NetBSD", (char const *)note.text)) {
ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD; ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD;
break; break;
} }
if (0==strcmp("OpenBSD", (char const *)&note.text)) { if (0==strcmp("OpenBSD", (char const *)note.text)) {
ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD; ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD;
break; break;
} }
+8 -11
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -87,26 +87,23 @@ protected:
unsigned n_mru; unsigned n_mru;
struct cprElfHdr1 { __packed_struct(cprElfHdr1)
Elf_LE32_Ehdr ehdr; Elf_LE32_Ehdr ehdr;
Elf_LE32_Phdr phdr[1]; Elf_LE32_Phdr phdr[1];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
struct cprElfHdr2 { __packed_struct(cprElfHdr2)
Elf_LE32_Ehdr ehdr; Elf_LE32_Ehdr ehdr;
Elf_LE32_Phdr phdr[2]; Elf_LE32_Phdr phdr[2];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
struct cprElfHdr3 { __packed_struct(cprElfHdr3)
Elf_LE32_Ehdr ehdr; Elf_LE32_Ehdr ehdr;
Elf_LE32_Phdr phdr[3]; Elf_LE32_Phdr phdr[3];
l_info linfo; l_info linfo;
} __packed_struct_end()
__attribute_packed;
cprElfHdr3 elfout; cprElfHdr3 elfout;
+10 -7
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -197,14 +197,17 @@ void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
void PackLinuxElf32x86interp::unpack(OutputFile *fo) void PackLinuxElf32x86interp::unpack(OutputFile *fo)
{ {
#define MAX_INTERP_HDR 512 #define MAX_INTERP_HDR 512
char bufehdr[MAX_INTERP_HDR]; union {
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)bufehdr; unsigned char buf[MAX_INTERP_HDR];
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ehdr); //struct { Elf32_Ehdr ehdr; Elf32_Phdr phdr; } e;
} u;
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *) u.buf;
Elf32_Phdr const *phdr = (Elf32_Phdr *) (u.buf + sizeof(*ehdr));
unsigned szb_info = sizeof(b_info); unsigned szb_info = sizeof(b_info);
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(bufehdr, MAX_INTERP_HDR); fi->readx(u.buf, MAX_INTERP_HDR);
unsigned const e_entry = get_te32(&ehdr->e_entry); unsigned const e_entry = get_te32(&ehdr->e_entry);
if (e_entry < 0x401180) { /* old style, 8-byte b_info */ if (e_entry < 0x401180) { /* old style, 8-byte b_info */
szb_info = 2*sizeof(unsigned); szb_info = 2*sizeof(unsigned);
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2000-2008 John F. Reiser Copyright (C) 2000-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+604 -52
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 2004-2008 John Reiser Copyright (C) 2004-2009 John Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -44,15 +44,49 @@ static const
static const static const
#include "stub/i386-darwin.macho-fold.h" #include "stub/i386-darwin.macho-fold.h"
static const
#include "stub/amd64-darwin.macho-entry.h"
static const
#include "stub/amd64-darwin.macho-fold.h"
static const
#include "stub/arm-darwin.macho-entry.h"
static const
#include "stub/arm-darwin.macho-fold.h"
// Packing a Darwin (Mach-o) Mac OS X dylib (dynamic shared library)
// is restricted. UPX gets control as the -init function, at the very
// end of processing by dyld. Relocation, loading of dependent libraries,
// etc., already have taken place before decompression. So the Mach-o
// headers, the __IMPORT segment, the __LINKEDIT segment, anything
// that is modifed by relocation, etc., cannot be compressed.
// We simplify arbitrarily by compressing only the __TEXT segment,
// which must be the first segment.
static const
#include "stub/i386-darwin.dylib-entry.h"
// The runtime stub for the dyld -init routine does not use "fold"ed code.
//#include "stub/i386-darwin.dylib-fold.h"
static const
#include "stub/powerpc-darwin.dylib-entry.h"
static const unsigned lc_segment[2] = {
0x1, 0x19
//Mach_segment_command::LC_SEGMENT,
//Mach_segment_command::LC_SEGMENT_64
};
template <class T> template <class T>
PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned flavor, PackMachBase<T>::PackMachBase(InputFile *f, unsigned cputype, unsigned filetype,
unsigned count, unsigned size) : unsigned flavor, unsigned count, unsigned size) :
super(f), my_cputype(cputype), my_thread_flavor(flavor), super(f), my_cputype(cputype), my_filetype(filetype), my_thread_flavor(flavor),
my_thread_state_word_count(count), my_thread_command_size(size), my_thread_state_word_count(count), my_thread_command_size(size),
n_segment(0), rawmseg(NULL), msegcmd(NULL) n_segment(0), rawmseg(NULL), msegcmd(NULL), o_routines_cmd(0),
prev_init_address(0)
{ {
MachClass::compileTimeAssertions(); MachClass::compileTimeAssertions();
bele = N_BELE_CTP::getRTP<BeLePolicy>(); bele = N_BELE_CTP::getRTP((const BeLePolicy*) NULL);
} }
template <class T> template <class T>
@@ -62,6 +96,16 @@ PackMachBase<T>::~PackMachBase()
delete [] msegcmd; delete [] msegcmd;
} }
PackDylibI386::PackDylibI386(InputFile *f) : super(f)
{
my_filetype = Mach_header::MH_DYLIB;
}
PackDylibPPC32::PackDylibPPC32(InputFile *f) : super(f)
{
my_filetype = Mach_header::MH_DYLIB;
}
template <class T> template <class T>
const int *PackMachBase<T>::getCompressionMethods(int method, int level) const const int *PackMachBase<T>::getCompressionMethods(int method, int level) const
{ {
@@ -69,6 +113,16 @@ const int *PackMachBase<T>::getCompressionMethods(int method, int level) const
return Packer::getDefaultCompressionMethods_le32(method, level); return Packer::getDefaultCompressionMethods_le32(method, level);
} }
const int *PackMachARMEL::getCompressionMethods(int method, int level) const
{
return Packer::getDefaultCompressionMethods_8(method, level);
}
PackMachPPC32::PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC,
Mach_header::MH_EXECUTE, Mach_thread_command::PPC_THREAD_STATE,
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado))
{ }
const int *PackMachPPC32::getFilters() const const int *PackMachPPC32::getFilters() const
{ {
@@ -76,12 +130,39 @@ const int *PackMachPPC32::getFilters() const
return filters; return filters;
} }
PackMachI386::PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386,
Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE32,
sizeof(Mach_i386_thread_state)>>2, sizeof(threado))
{ }
int const *PackMachI386::getFilters() const int const *PackMachI386::getFilters() const
{ {
static const int filters[] = { 0x49, FT_END }; static const int filters[] = { 0x49, FT_END };
return filters; return filters;
} }
PackMachAMD64::PackMachAMD64(InputFile *f) : super(f, Mach_header::CPU_TYPE_X86_64,
Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::x86_THREAD_STATE64,
sizeof(Mach_AMD64_thread_state)>>2, sizeof(threado))
{ }
int const *PackMachAMD64::getFilters() const
{
static const int filters[] = { 0x49, FT_END };
return filters;
}
PackMachARMEL::PackMachARMEL(InputFile *f) : super(f, Mach_header::CPU_TYPE_ARM,
Mach_header::MH_EXECUTE, (unsigned)Mach_thread_command::ARM_THREAD_STATE,
sizeof(Mach_ARM_thread_state)>>2, sizeof(threado))
{ }
int const *PackMachARMEL::getFilters() const
{
static const int filters[] = { 0x50, FT_END };
return filters;
}
Linker *PackMachPPC32::newLinker() const Linker *PackMachPPC32::newLinker() const
{ {
return new ElfLinkerPpc32; return new ElfLinkerPpc32;
@@ -92,6 +173,16 @@ Linker *PackMachI386::newLinker() const
return new ElfLinkerX86; return new ElfLinkerX86;
} }
Linker *PackMachAMD64::newLinker() const
{
return new ElfLinkerAMD64;
}
Linker *PackMachARMEL::newLinker() const
{
return new ElfLinkerArmLE;
}
template <class T> template <class T>
void void
PackMachBase<T>::addStubEntrySections(Filter const *) PackMachBase<T>::addStubEntrySections(Filter const *)
@@ -171,6 +262,35 @@ void PackMachI386::addStubEntrySections(Filter const *ft)
addLoader("FOLDEXEC", NULL); addLoader("FOLDEXEC", NULL);
} }
void PackMachAMD64::addStubEntrySections(Filter const */*ft*/)
{
addLoader("MACHMAINX", NULL);
//addLoader(getDecompressorSections(), NULL);
addLoader(
( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,+80C,LZMA_DEC20,LZMA_DEC30"
: NULL), NULL);
if (hasLoaderSection("CFLUSH"))
addLoader("CFLUSH");
addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL);
}
void PackMachARMEL::addStubEntrySections(Filter const */*ft*/)
{
addLoader("MACHMAINX", NULL);
//addLoader(getDecompressorSections(), NULL);
addLoader(
( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,+80C,LZMA_DEC20,LZMA_DEC30"
: NULL), NULL);
if (hasLoaderSection("CFLUSH"))
addLoader("CFLUSH");
addLoader("MACHMAINY,IDENTSTR,+40,MACHMAINZ,FOLDEXEC", NULL);
}
template <class T> template <class T>
void PackMachBase<T>::defineSymbols(Filter const *) void PackMachBase<T>::defineSymbols(Filter const *)
@@ -217,7 +337,8 @@ PackMachBase<T>::buildMachLoader(
delete [] cprLoader; delete [] cprLoader;
int const GAP = 128; // must match stub/l_mac_ppc.S int const GAP = 128; // must match stub/l_mac_ppc.S
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64; int const NO_LAP = 64; // must match stub/src/*darwin*.S
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + NO_LAP;
addStubEntrySections(ft); addStubEntrySections(ft);
@@ -241,6 +362,38 @@ PackMachI386::buildLoader(const Filter *ft)
stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft ); stub_i386_darwin_macho_fold, sizeof(stub_i386_darwin_macho_fold), ft );
} }
void
PackMachAMD64::buildLoader(const Filter *ft)
{
buildMachLoader(
stub_amd64_darwin_macho_entry, sizeof(stub_amd64_darwin_macho_entry),
stub_amd64_darwin_macho_fold, sizeof(stub_amd64_darwin_macho_fold), ft );
}
void
PackMachARMEL::buildLoader(const Filter *ft)
{
buildMachLoader(
stub_arm_darwin_macho_entry, sizeof(stub_arm_darwin_macho_entry),
stub_arm_darwin_macho_fold, sizeof(stub_arm_darwin_macho_fold), ft );
}
void
PackDylibI386::buildLoader(const Filter *ft)
{
buildMachLoader(
stub_i386_darwin_dylib_entry, sizeof(stub_i386_darwin_dylib_entry),
0, 0, ft );
}
void
PackDylibPPC32::buildLoader(const Filter *ft)
{
buildMachLoader(
stub_powerpc_darwin_dylib_entry, sizeof(stub_powerpc_darwin_dylib_entry),
0, 0, ft );
}
template <class T> template <class T>
void PackMachBase<T>::patchLoader() { } void PackMachBase<T>::patchLoader() { }
@@ -268,8 +421,9 @@ PackMachBase<T>::compare_segment_command(void const *const aa, void const *const
{ {
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;
unsigned const xa = a->cmd - Mach_segment_command::LC_SEGMENT; unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
unsigned const xb = b->cmd - Mach_segment_command::LC_SEGMENT; unsigned const xa = a->cmd - lc_seg;
unsigned const xb = b->cmd - lc_seg;
if (xa < xb) return -1; // LC_SEGMENT first if (xa < xb) return -1; // LC_SEGMENT first
if (xa > xb) return 1; if (xa > xb) return 1;
if (a->vmaddr < b->vmaddr) return -1; // ascending by .vmaddr if (a->vmaddr < b->vmaddr) return -1; // ascending by .vmaddr
@@ -305,9 +459,190 @@ void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
fo->rewrite(&linfo, sizeof(linfo)); fo->rewrite(&linfo, sizeof(linfo));
} }
void PackMachAMD64::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{
// 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 PackMachARMEL::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{
// 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));
}
#undef PAGE_MASK
#undef PAGE_SIZE
#define PAGE_MASK (~0u<<12)
#define PAGE_SIZE -PAGE_MASK
#undef PAGE_MASK64
#undef PAGE_SIZE64
#define PAGE_MASK64 (~(acc_uint64l_t)0<<12)
#define PAGE_SIZE64 -PAGE_MASK64
template <class T>
void PackMachBase<T>::pack4dylib( // append PackHeader
OutputFile *const fo,
Filter &ft,
Addr init_address
)
{
unsigned opos = sizeof(mhdro);
fo->seek(opos, SEEK_SET);
// Append each non-__TEXT segment, page aligned.
int slide = 0;
unsigned o_end_txt = 0;
unsigned hdrpos = sizeof(mhdro);
Mach_segment_command const *seg = rawmseg;
Mach_segment_command const *const endseg =
(Mach_segment_command const *)(mhdri.sizeofcmds + (char const *)seg);
for ( ; seg < endseg; seg = (Mach_segment_command const *)(
seg->cmdsize + (char const *)seg )
) switch (~Mach_segment_command::LC_REQ_DYLD & seg->cmd) {
default: // unknown if any file offset field must slide
printf("Unrecognized Macho cmd offset=0x%lx cmd=0x%lx size=0x%lx\n", (unsigned long)((const char *)seg - (const char *)rawmseg), (unsigned long)seg->cmd, (unsigned long)seg->cmdsize);
// fall through
case Mach_segment_command::LC_THREAD:
case Mach_segment_command::LC_UNIXTHREAD:
case Mach_segment_command::LC_LOAD_DYLIB:
case Mach_segment_command::LC_ID_DYLIB:
case Mach_segment_command::LC_LOAD_DYLINKER:
case Mach_segment_command::LC_UUID:
case Mach_segment_command::LC_RPATH:
case Mach_segment_command::LC_CODE_SIGNATURE:
case Mach_segment_command::LC_REEXPORT_DYLIB:
hdrpos += seg->cmdsize;
break; // contain no file offset fields
case Mach_segment_command::LC_TWOLEVEL_HINTS: {
Mach_twolevel_hints_command cmd; memcpy(&cmd, seg, sizeof(cmd));
if (o_end_txt <= cmd.offset) { cmd.offset += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
case Mach_segment_command::LC_ROUTINES_64:
case Mach_segment_command::LC_ROUTINES: {
Mach_routines_command cmd; memcpy(&cmd, seg, sizeof(cmd));
cmd.reserved1 = cmd.init_address;
cmd.init_address = init_address;
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
case Mach_segment_command::LC_SEGMENT_64:
case Mach_segment_command::LC_SEGMENT: {
// non-__TEXT might be observed and relocated by dyld before us.
Mach_segment_command segcmdtmp = *seg;
bool const is_text = 0==strncmp(&seg->segname[0], "__TEXT", 1+ 6);
{
if (is_text) {
slide = 0;
segcmdtmp.filesize = fo->getBytesWritten();
segcmdtmp.maxprot |= Mach_segment_command::VM_PROT_WRITE;
segcmdtmp.initprot |= Mach_segment_command::VM_PROT_WRITE;
opos = o_end_txt = segcmdtmp.filesize + segcmdtmp.fileoff;
}
else {
opos += ~PAGE_MASK & (0u - opos); // advance to PAGE_SIZE boundary
slide = opos - segcmdtmp.fileoff;
segcmdtmp.fileoff = opos;
}
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&segcmdtmp, sizeof(segcmdtmp));
hdrpos += sizeof(segcmdtmp);
// Update the sections.
Mach_section_command const *secp = (Mach_section_command const *)(const void*)(const char*)(1+ seg);
unsigned const nsects = segcmdtmp.nsects;
Mach_section_command seccmdtmp;
for (unsigned j = 0; j < nsects; ++secp, ++j) {
seccmdtmp = *secp;
seccmdtmp.offset += slide;
if (seccmdtmp.nreloc) {
seccmdtmp.reloff += slide;
}
fo->rewrite(&seccmdtmp, sizeof(seccmdtmp));
hdrpos += sizeof(seccmdtmp);
}
if (!is_text) {
fo->seek(opos, SEEK_SET);
fi->seek(seg->fileoff, SEEK_SET);
unsigned const len = seg->filesize;
MemBuffer data(len);
fi->readx(data, len);
fo->write(data, len);
opos += len;
}
}
} break;
case Mach_segment_command::LC_SYMTAB: {
Mach_symtab_command cmd; memcpy(&cmd, seg, sizeof(cmd));
if (o_end_txt <= cmd.symoff) { cmd.symoff += slide; }
if (o_end_txt <= cmd.stroff) { cmd.stroff += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
case Mach_segment_command::LC_DYSYMTAB: {
Mach_dysymtab_command cmd; memcpy(&cmd, seg, sizeof(cmd));
if (o_end_txt <= cmd.tocoff) { cmd.tocoff += slide; }
if (o_end_txt <= cmd.modtaboff) { cmd.modtaboff += slide; }
if (o_end_txt <= cmd.extrefsymoff) { cmd.extrefsymoff += slide; }
if (o_end_txt <= cmd.indirectsymoff) { cmd.indirectsymoff += slide; }
if (o_end_txt <= cmd.extreloff) { cmd.extreloff += slide; }
if (o_end_txt <= cmd.locreloff) { cmd.locreloff += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
case Mach_segment_command::LC_SEGMENT_SPLIT_INFO: {
Mach_segsplit_info_command cmd; memcpy(&cmd, seg, sizeof(cmd));
if (o_end_txt <= cmd.dataoff) { cmd.dataoff += slide; }
fo->seek(hdrpos, SEEK_SET);
fo->rewrite(&cmd, sizeof(cmd));
hdrpos += sizeof(cmd);
} break;
} // end 'switch'
fo->seek(opos, SEEK_SET); // BUG: "fo->seek(0, SEEK_END);" is broken
// offset of p_info in compressed file
overlay_offset = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(linfo);
PackMachBase<T>::pack4(fo, ft);
}
void PackDylibI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{
pack4dylib(fo, ft, threado.state.eip);
}
void PackDylibPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
{
pack4dylib(fo, ft, threado.state.srr0);
}
void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
BE32 disp; TE32 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));
@@ -321,7 +656,7 @@ void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
{ {
LE32 disp; TE32 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));
@@ -333,6 +668,80 @@ void PackMachI386::pack3(OutputFile *fo, Filter &ft) // append loader
super::pack3(fo, ft); super::pack3(fo, ft);
} }
void PackMachAMD64::pack3(OutputFile *fo, Filter &ft) // append loader
{
TE32 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.rip = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
super::pack3(fo, ft);
}
void PackMachARMEL::pack3(OutputFile *fo, Filter &ft) // append loader
{
TE32 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.pc = len + sizeof(disp) + segcmdo.vmaddr; /* entry address */
super::pack3(fo, ft);
}
void PackDylibI386::pack3(OutputFile *fo, Filter &ft) // append loader
{
TE32 disp;
unsigned const zero = 0;
unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len));
len += (3& (0u-len)) + 4*sizeof(disp);
disp = prev_init_address;
fo->write(&disp, sizeof(disp)); // user .init_address
disp = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(l_info) + sizeof(p_info);
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
disp = len - disp - 3*sizeof(disp);
fo->write(&disp, sizeof(disp)); // length(compressed __TEXT)
unsigned const save_sz_mach_headers(sz_mach_headers);
sz_mach_headers = 0;
super::pack3(fo, ft);
sz_mach_headers = save_sz_mach_headers;
}
void PackDylibPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
{
TE32 disp;
unsigned const zero = 0;
unsigned len = fo->getBytesWritten();
fo->write(&zero, 3& (0u-len));
len += (3& (0u-len)) + 4*sizeof(disp);
disp = prev_init_address;
fo->write(&disp, sizeof(disp)); // user .init_address
disp = sizeof(mhdro) + mhdro.sizeofcmds + sizeof(l_info) + sizeof(p_info);
fo->write(&disp, sizeof(disp)); // src offset(compressed __TEXT)
disp = len - disp - 3*sizeof(disp);
fo->write(&disp, sizeof(disp)); // length(compressed __TEXT)
unsigned const save_sz_mach_headers(sz_mach_headers);
sz_mach_headers = 0;
super::pack3(fo, ft);
sz_mach_headers = save_sz_mach_headers;
}
// 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.
@@ -342,7 +751,8 @@ unsigned PackMachBase<T>::find_SEGMENT_gap(
unsigned const k unsigned const k
) )
{ {
if (Mach_segment_command::LC_SEGMENT!=msegcmd[k].cmd unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
if (lc_seg!=msegcmd[k].cmd
|| 0==msegcmd[k].filesize ) { || 0==msegcmd[k].filesize ) {
return 0; return 0;
} }
@@ -357,7 +767,7 @@ unsigned PackMachBase<T>::find_SEGMENT_gap(
if (k==j) { if (k==j) {
break; break;
} }
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd if (lc_seg==msegcmd[j].cmd
&& 0!=msegcmd[j].filesize ) { && 0!=msegcmd[j].filesize ) {
unsigned const t = msegcmd[j].fileoff; unsigned const t = msegcmd[j].fileoff;
if ((t - hi) < (lo - hi)) { if ((t - hi) < (lo - hi)) {
@@ -386,15 +796,19 @@ void PackMachBase<T>::pack3(OutputFile *fo, Filter &ft)
template <class T> template <class T>
void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed body void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed body
{ {
unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
Extent x; Extent x;
unsigned k; unsigned k;
// count passes, set ptload vars // count passes, set ptload vars
uip->ui_total_passes = 0; uip->ui_total_passes = 0;
for (k = 0; k < n_segment; ++k) { for (k = 0; k < n_segment; ++k) {
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd if (lc_seg==msegcmd[k].cmd
&& 0!=msegcmd[k].filesize ) { && 0!=msegcmd[k].filesize ) {
uip->ui_total_passes++; uip->ui_total_passes++;
if (my_filetype==Mach_header::MH_DYLIB) {
break;
}
if (find_SEGMENT_gap(k)) { if (find_SEGMENT_gap(k)) {
uip->ui_total_passes++; uip->ui_total_passes++;
} }
@@ -405,7 +819,7 @@ void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
unsigned total_in = 0; unsigned total_in = 0;
unsigned total_out = 0; unsigned total_out = 0;
unsigned hdr_u_len = mhdri.sizeofcmds; unsigned hdr_u_len = mhdri.sizeofcmds + sizeof(mhdri);
uip->ui_pass = 0; uip->ui_pass = 0;
ft.addvalue = 0; ft.addvalue = 0;
@@ -415,7 +829,7 @@ void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
// instructions. So filter only the largest executable segment. // instructions. So filter only the largest executable segment.
unsigned exe_filesize_max = 0; unsigned exe_filesize_max = 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 (lc_seg==msegcmd[k].cmd
&& 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot) && 0!=(Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
&& exe_filesize_max < msegcmd[k].filesize) { && exe_filesize_max < msegcmd[k].filesize) {
exe_filesize_max = msegcmd[k].filesize; exe_filesize_max = msegcmd[k].filesize;
@@ -423,12 +837,12 @@ void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
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 (lc_seg==msegcmd[k].cmd
&& 0!=msegcmd[k].filesize ) { && 0!=msegcmd[k].filesize ) {
x.offset = msegcmd[k].fileoff; x.offset = msegcmd[k].fileoff;
x.size = msegcmd[k].filesize; x.size = msegcmd[k].filesize;
if (0 == nx) { // 1st LC_SEGMENT must cover Mach_header at 0==fileoffset if (0 == nx) { // 1st LC_SEGMENT must cover Mach_header at 0==fileoffset
unsigned const delta = mhdri.sizeofcmds; unsigned const delta = mhdri.sizeofcmds + sizeof(mhdri);
x.offset += delta; x.offset += delta;
x.size -= delta; x.size -= delta;
} }
@@ -441,7 +855,11 @@ void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
} }
hdr_u_len = 0; hdr_u_len = 0;
++nx; ++nx;
if (my_filetype==Mach_header::MH_DYLIB) {
break;
} }
}
if (my_filetype!=Mach_header::MH_DYLIB)
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) {
@@ -450,16 +868,12 @@ void PackMachBase<T>::pack2(OutputFile *fo, Filter &ft) // append compressed bo
} }
} }
if (my_filetype!=Mach_header::MH_DYLIB)
if ((off_t)total_in != file_size) if ((off_t)total_in != file_size)
throwEOFException(); throwEOFException();
segcmdo.filesize = fo->getBytesWritten(); segcmdo.filesize = fo->getBytesWritten();
} }
#undef PAGE_MASK
#undef PAGE_SIZE
#define PAGE_MASK (~0u<<12)
#define PAGE_SIZE -PAGE_MASK
void PackMachPPC32::pack1_setup_threado(OutputFile *const fo) void PackMachPPC32::pack1_setup_threado(OutputFile *const fo)
{ {
threado.cmd = Mach_segment_command::LC_UNIXTHREAD; threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
@@ -480,20 +894,48 @@ void PackMachI386::pack1_setup_threado(OutputFile *const fo)
fo->write(&threado, sizeof(threado)); fo->write(&threado, sizeof(threado));
} }
void PackMachAMD64::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 PackMachARMEL::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> template <class T>
void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate executable header
{ {
unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
mhdro = mhdri; mhdro = mhdri;
if (my_filetype==Mach_header::MH_EXECUTE) {
mhdro.ncmds = 2; mhdro.ncmds = 2;
mhdro.sizeofcmds = sizeof(segcmdo) + my_thread_command_size; 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));
segcmdo.cmd = Mach_segment_command::LC_SEGMENT; segcmdo.cmd = lc_seg;
segcmdo.cmdsize = sizeof(segcmdo); segcmdo.cmdsize = sizeof(segcmdo);
strncpy((char *)&segcmdo.segname, "__TEXT", sizeof(segcmdo.segname)); strncpy((char *)segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));
segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK + if (my_filetype==Mach_header::MH_EXECUTE) {
segcmdo.vmaddr = PAGE_MASK64 & (~PAGE_MASK64 +
msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr ); msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr );
}
if (my_filetype==Mach_header::MH_DYLIB) {
segcmdo.vmaddr = 0;
}
segcmdo.vmsize = 0; // adjust later segcmdo.vmsize = 0; // adjust later
segcmdo.fileoff = 0; segcmdo.fileoff = 0;
segcmdo.filesize = 0; // adjust later segcmdo.filesize = 0; // adjust later
@@ -503,9 +945,13 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
Mach_segment_command::VM_PROT_EXECUTE; Mach_segment_command::VM_PROT_EXECUTE;
segcmdo.nsects = 0; segcmdo.nsects = 0;
segcmdo.flags = 0; segcmdo.flags = 0;
if (my_filetype==Mach_header::MH_EXECUTE) {
fo->write(&segcmdo, sizeof(segcmdo)); fo->write(&segcmdo, sizeof(segcmdo));
pack1_setup_threado(fo); pack1_setup_threado(fo);
}
if (my_filetype==Mach_header::MH_DYLIB) {
fo->write(rawmseg, mhdri.sizeofcmds);
}
sz_mach_headers = fo->getBytesWritten(); sz_mach_headers = fo->getBytesWritten();
memset((char *)&linfo, 0, sizeof(linfo)); memset((char *)&linfo, 0, sizeof(linfo));
@@ -517,8 +963,12 @@ void PackMachBase<T>::pack1(OutputFile *const fo, Filter &/*ft*/) // generate e
template <class T> template <class T>
void PackMachBase<T>::unpack(OutputFile *fo) void PackMachBase<T>::unpack(OutputFile *fo)
{ {
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
my_thread_command_size + sizeof(linfo); fi->seek(0, SEEK_SET);
fi->readx(&mhdri, sizeof(mhdri));
rawmseg = (Mach_segment_command *)new char[(unsigned) mhdri.sizeofcmds];
fi->readx(rawmseg, mhdri.sizeofcmds);
overlay_offset = sizeof(mhdri) + mhdri.sizeofcmds + 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));
@@ -553,14 +1003,14 @@ void PackMachBase<T>::unpack(OutputFile *fo)
qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command); qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command);
n_segment = 0; n_segment = 0;
for (unsigned j= 0; j < ncmds; ++j) { for (unsigned j= 0; j < ncmds; ++j) {
n_segment += (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd); n_segment += (lc_seg==msegcmd[j].cmd);
} }
unsigned total_in = 0; unsigned total_in = 0;
unsigned total_out = 0; unsigned total_out = 0;
unsigned c_adler = upx_adler32(NULL, 0); unsigned c_adler = upx_adler32(NULL, 0);
unsigned u_adler = upx_adler32(NULL, 0); unsigned u_adler = upx_adler32(NULL, 0);
Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr); Mach_segment_command const *sc = (Mach_segment_command const *)(void *)(1+ mhdr);
unsigned k; unsigned k;
fi->seek(- (off_t)(sizeof(bhdr) + ph.c_len), SEEK_CUR); fi->seek(- (off_t)(sizeof(bhdr) + ph.c_len), SEEK_CUR);
@@ -569,12 +1019,38 @@ void PackMachBase<T>::unpack(OutputFile *fo)
k < ncmds; k < ncmds;
(++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc)) (++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))
) { ) {
if (Mach_segment_command::LC_SEGMENT==sc->cmd if (lc_seg==sc->cmd
&& 0!=sc->filesize ) { && 0!=sc->filesize ) {
unsigned filesize = 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));
if (my_filetype==Mach_header::MH_DYLIB) {
break;
} }
} }
}
if (my_filetype==Mach_header::MH_DYLIB) {
Mach_segment_command const *rc = rawmseg;
rc = (Mach_segment_command const *)(rc->cmdsize + (char const *)rc);
sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc);
for (
k=1;
k < ncmds;
(++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc)),
(rc = (Mach_segment_command const *)(rc->cmdsize + (char const *)rc))
) {
if (lc_seg==rc->cmd
&& 0!=rc->filesize ) {
fi->seek(rc->fileoff, SEEK_SET);
fo->seek(sc->fileoff, SEEK_SET);
unsigned const len = rc->filesize;
MemBuffer data(len);
fi->readx(data, len);
fo->write(data, len);
}
}
}
else
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) {
@@ -585,44 +1061,55 @@ void PackMachBase<T>::unpack(OutputFile *fo)
c_adler, u_adler, false, sizeof(bhdr)); c_adler, u_adler, false, sizeof(bhdr));
} }
} }
delete mhdr;
} }
template <class T> template <class T>
bool PackMachBase<T>::canPack() bool PackMachBase<T>::canPack()
{ {
unsigned const lc_seg = lc_segment[sizeof(Addr)>>3];
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 + (sizeof(Addr)>>3)) !=mhdri.magic
|| my_cputype !=mhdri.cputype || my_cputype !=mhdri.cputype
|| Mach_header::MH_EXECUTE !=mhdri.filetype || my_filetype !=mhdri.filetype
) )
return false; return false;
rawmseg = (Mach_segment_command *)new char[mhdri.sizeofcmds]; rawmseg = (Mach_segment_command *)new char[(unsigned) mhdri.sizeofcmds];
fi->readx(rawmseg, mhdri.sizeofcmds); fi->readx(rawmseg, mhdri.sizeofcmds);
msegcmd = new Mach_segment_command[mhdri.ncmds]; unsigned const ncmds = mhdri.ncmds;
unsigned char *ptr = (unsigned char *)rawmseg; msegcmd = new Mach_segment_command[ncmds];
for (unsigned j= 0; j < mhdri.ncmds; ++j) { unsigned char const *ptr = (unsigned char const *)rawmseg;
msegcmd[j] = *(Mach_segment_command *)ptr; for (unsigned j= 0; j < ncmds; ++j) {
ptr += (unsigned) ((Mach_segment_command *)ptr)->cmdsize; msegcmd[j] = *(Mach_segment_command const *)ptr;
if (((Mach_segment_command const *)ptr)->cmd ==
Mach_segment_command::LC_ROUTINES) {
o_routines_cmd = (const char *)ptr - (const char *)rawmseg;
prev_init_address = ((Mach_routines_command const *)ptr)->init_address;
}
ptr += (unsigned) ((const Mach_segment_command *)ptr)->cmdsize;
}
if (Mach_header::MH_DYLIB==my_filetype && 0==o_routines_cmd) {
infoWarning("missing -init function");
return false;
} }
// Put LC_SEGMENT together at the beginning, ascending by .vmaddr. // Put LC_SEGMENT together at the beginning, ascending by .vmaddr.
qsort(msegcmd, mhdri.ncmds, sizeof(*msegcmd), compare_segment_command); qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command);
// Check that LC_SEGMENTs form one contiguous chunk of the file. // Check that LC_SEGMENTs form one contiguous chunk of the file.
for (unsigned j= 0; j < mhdri.ncmds; ++j) { for (unsigned j= 0; j < ncmds; ++j) {
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) { if (lc_seg==msegcmd[j].cmd) {
if (0xfff & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) { if (~PAGE_MASK & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {
return false; return false;
} }
if (0 < j) { if (0 < j) {
unsigned const sz = ~0xfff unsigned const sz = PAGE_MASK
& (0xfff + msegcmd[j-1].filesize); & (~PAGE_MASK + msegcmd[j-1].filesize);
if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) { if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) {
return false; return false;
} }
@@ -645,6 +1132,7 @@ bool PackMachBase<T>::canPack()
template class PackMachBase<MachClass_BE32>; template class PackMachBase<MachClass_BE32>;
template class PackMachBase<MachClass_LE32>; template class PackMachBase<MachClass_LE32>;
template class PackMachBase<MachClass_LE64>;
PackMachFat::PackMachFat(InputFile *f) : super(f) PackMachFat::PackMachFat(InputFile *f) : super(f)
@@ -684,18 +1172,42 @@ void PackMachFat::pack(OutputFile *fo)
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size); fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (fat_head.arch[j].cputype) { switch (fat_head.arch[j].cputype) {
case PackMachFat::CPU_TYPE_I386: { case PackMachFat::CPU_TYPE_I386: {
typedef N_Mach::Mach_header<MachClass_LE32::MachITypes> Mach_header;
Mach_header hdr;
fi->readx(&hdr, sizeof(hdr));
if (hdr.filetype==Mach_header::MH_EXECUTE) {
PackMachI386 packer(fi); PackMachI386 packer(fi);
packer.initPackHeader(); packer.initPackHeader();
packer.canPack(); packer.canPack();
packer.updatePackHeader(); packer.updatePackHeader();
packer.pack(fo); packer.pack(fo);
}
else if (hdr.filetype==Mach_header::MH_DYLIB) {
PackDylibI386 packer(fi);
packer.initPackHeader();
packer.canPack();
packer.updatePackHeader();
packer.pack(fo);
}
} break; } break;
case PackMachFat::CPU_TYPE_POWERPC: { case PackMachFat::CPU_TYPE_POWERPC: {
typedef N_Mach::Mach_header<MachClass_BE32::MachITypes> Mach_header;
Mach_header hdr;
fi->readx(&hdr, sizeof(hdr));
if (hdr.filetype==Mach_header::MH_EXECUTE) {
PackMachPPC32 packer(fi); PackMachPPC32 packer(fi);
packer.initPackHeader(); packer.initPackHeader();
packer.canPack(); packer.canPack();
packer.updatePackHeader(); packer.updatePackHeader();
packer.pack(fo); packer.pack(fo);
}
else if (hdr.filetype==Mach_header::MH_DYLIB) {
PackDylibPPC32 packer(fi);
packer.initPackHeader();
packer.canPack();
packer.updatePackHeader();
packer.pack(fo);
}
} break; } break;
} // switch cputype } // switch cputype
fat_head.arch[j].offset = base; fat_head.arch[j].offset = base;
@@ -727,16 +1239,38 @@ void PackMachFat::unpack(OutputFile *fo)
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size); fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
switch (fat_head.arch[j].cputype) { switch (fat_head.arch[j].cputype) {
case PackMachFat::CPU_TYPE_I386: { case PackMachFat::CPU_TYPE_I386: {
N_Mach::Mach_header<MachClass_LE32::MachITypes> hdr;
typedef N_Mach::Mach_header<MachClass_LE32::MachITypes> Mach_header;
fi->readx(&hdr, sizeof(hdr));
if (hdr.filetype==Mach_header::MH_EXECUTE) {
PackMachI386 packer(fi); PackMachI386 packer(fi);
packer.initPackHeader(); packer.initPackHeader();
packer.canUnpack(); packer.canUnpack();
packer.unpack(fo); packer.unpack(fo);
}
else if (hdr.filetype==Mach_header::MH_DYLIB) {
PackDylibI386 packer(fi);
packer.initPackHeader();
packer.canUnpack();
packer.unpack(fo);
}
} break; } break;
case PackMachFat::CPU_TYPE_POWERPC: { case PackMachFat::CPU_TYPE_POWERPC: {
N_Mach::Mach_header<MachClass_BE32::MachITypes> hdr;
typedef N_Mach::Mach_header<MachClass_BE32::MachITypes> Mach_header;
fi->readx(&hdr, sizeof(hdr));
if (hdr.filetype==Mach_header::MH_EXECUTE) {
PackMachPPC32 packer(fi); PackMachPPC32 packer(fi);
packer.initPackHeader(); packer.initPackHeader();
packer.canUnpack(); packer.canUnpack();
packer.unpack(fo); packer.unpack(fo);
}
else if (hdr.filetype==Mach_header::MH_DYLIB) {
PackDylibPPC32 packer(fi);
packer.initPackHeader();
packer.canUnpack();
packer.unpack(fo);
}
} break; } break;
} // switch cputype } // switch cputype
fat_head.arch[j].offset = base; fat_head.arch[j].offset = base;
@@ -764,13 +1298,19 @@ bool PackMachFat::canPack()
default: return false; default: return false;
case PackMachFat::CPU_TYPE_I386: { case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi); PackMachI386 packer(fi);
if (!packer.canPack()) if (!packer.canPack()) {
PackDylibI386 pack2r(fi);
if (!pack2r.canPack())
return false; return false;
}
} break; } break;
case PackMachFat::CPU_TYPE_POWERPC: { case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi); PackMachPPC32 packer(fi);
if (!packer.canPack()) if (!packer.canPack()) {
PackDylibPPC32 pack2r(fi);
if (!pack2r.canPack())
return false; return false;
}
} break; } break;
} // switch cputype } // switch cputype
} }
@@ -799,14 +1339,26 @@ int PackMachFat::canUnpack()
default: return false; default: return false;
case PackMachFat::CPU_TYPE_I386: { case PackMachFat::CPU_TYPE_I386: {
PackMachI386 packer(fi); PackMachI386 packer(fi);
if (!packer.canUnpack()) if (!packer.canUnpack()) {
PackDylibI386 pack2r(fi);
if (!pack2r.canUnpack())
return 0; return 0;
else
ph.format = pack2r.getFormat(); // FIXME: copy entire PackHeader
}
else
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
} break; } break;
case PackMachFat::CPU_TYPE_POWERPC: { case PackMachFat::CPU_TYPE_POWERPC: {
PackMachPPC32 packer(fi); PackMachPPC32 packer(fi);
if (!packer.canUnpack()) if (!packer.canUnpack()) {
PackDylibPPC32 pack2r(fi);
if (!pack2r.canUnpack())
return 0; return 0;
else
ph.format = pack2r.getFormat(); // FIXME: copy entire PackHeader
}
else
ph.format = packer.getFormat(); // FIXME: copy entire PackHeader ph.format = packer.getFormat(); // FIXME: copy entire PackHeader
} break; } break;
} // switch cputype } // switch cputype
+330 -67
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -30,24 +30,22 @@
#define __UPX_P_MACHO_H #define __UPX_P_MACHO_H
struct Mach_fat_header { __packed_struct(Mach_fat_header)
BE32 magic; BE32 magic;
enum { // note conflict with java bytecode PackLinuxI386 enum { // note conflict with java bytecode PackLinuxI386
FAT_MAGIC = 0xcafebabe, FAT_MAGIC = 0xcafebabe,
FAT_MAGIC_SWAB = 0xbebafeca FAT_MAGIC_SWAB = 0xbebafeca
}; };
BE32 nfat_arch; // Number of Mach_fat_arch which follow. BE32 nfat_arch; // Number of Mach_fat_arch which follow.
} __packed_struct_end()
__attribute_packed;
struct Mach_fat_arch { __packed_struct(Mach_fat_arch)
BE32 cputype; BE32 cputype;
BE32 cpusubtype; BE32 cpusubtype;
BE32 offset; BE32 offset;
BE32 size; BE32 size;
BE32 align; /* shift count; log base 2 */ BE32 align; /* shift count; log base 2 */
} __packed_struct_end()
__attribute_packed;
/************************************************************************* /*************************************************************************
@@ -68,8 +66,7 @@ struct MachITypes
}; };
template <class TMachITypes> template <class TMachITypes>
struct Mach_header __packed_struct(Mach_header)
{
typedef typename TMachITypes::Word Word; typedef typename TMachITypes::Word Word;
Word magic; Word magic;
@@ -81,12 +78,11 @@ struct Mach_header
Word flags; Word flags;
#define WANT_MACH_HEADER_ENUM 1 #define WANT_MACH_HEADER_ENUM 1
#include "p_mach_enum.h" #include "p_mach_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes> template <class TMachITypes>
struct Mach_header64 __packed_struct(Mach_header64)
{ // only difference is padding to 0 mod 8 // only difference is padding to 0 mod 8
typedef typename TMachITypes::Word Word; typedef typename TMachITypes::Word Word;
Word magic; Word magic;
@@ -99,12 +95,10 @@ struct Mach_header64
Word reserved; // pad to 0 mod 8 Word reserved; // pad to 0 mod 8
#define WANT_MACH_HEADER_ENUM 1 #define WANT_MACH_HEADER_ENUM 1
#include "p_mach_enum.h" #include "p_mach_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes> template <class TMachITypes>
struct Mach_segment_command __packed_struct(Mach_segment_command)
{
typedef typename TMachITypes::Word Word; typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr; typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off; typedef typename TMachITypes::Off Off;
@@ -122,12 +116,10 @@ struct Mach_segment_command
Word flags; Word flags;
#define WANT_MACH_SEGMENT_ENUM 1 #define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h" #include "p_mach_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes> template <class TMachITypes>
struct Mach_section_command __packed_struct(Mach_section_command)
{
typedef typename TMachITypes::Word Word; typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr; typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off; typedef typename TMachITypes::Off Off;
@@ -145,12 +137,95 @@ struct Mach_section_command
Word reserved2; Word reserved2;
#define WANT_MACH_SECTION_ENUM 1 #define WANT_MACH_SECTION_ENUM 1
#include "p_mach_enum.h" #include "p_mach_enum.h"
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes> template <class TMachITypes>
struct Mach_ppc_thread_state __packed_struct(Mach_symtab_command)
{ typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Off Off;
Word cmd; /* LC_SYMTAB */
Word cmdsize; /* sizeof(struct Mach_symtab_command) */
Off symoff; /* symbol table offset */
Word nsyms; /* number of symbol table entries */
Off stroff; /* string table offset */
Word strsize; /* string table size in bytes */
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_dysymtab_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Off Off;
Word cmd; /* LC_DYSYMTAB */
Word cmdsize; /* sizeof(struct Mach_dysymtab_command) */
Word ilocalsym; /* index to local symbols */
Word nlocalsym; /* number of local symbols */
Word iextdefsym; /* index to externally defined symbols */
Word nextdefsym; /* number of externally defined symbols */
Word iundefsym; /* index to undefined symbols */
Word nundefsym; /* number of undefined symbols */
Off tocoff; /* file offset to table of contents */
Word ntoc; /* number of entries in table of contents */
Off modtaboff; /* file offset to module table */
Word nmodtab; /* number of module table entries */
Off extrefsymoff; /* offset to referenced symbol table */
Word nextrefsymoff; /* number of referenced symbol table entries */
Off indirectsymoff; /* file offset to the indirect symbol table */
Word nindirectsyms; /* number of indirect symbol table entries */
Off extreloff; /* offset to external relocation entries */
Word nextrel; /* number of external relocation entries */
Off locreloff; /* offset to local relocation entries */
Word nlocrel; /* number of local relocation entries */
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_segsplit_info_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Off Off;
Word cmd; /* LC_SEGMENT_SPLIT_INFO */
Word cmdsize; /* sizeof(struct Mach_segsplit_info_command) */
Off dataoff;
Word datasize;
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_routines_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off;
Word cmd;
Word cmdsize;
Addr init_address;
Word init_module;
Word reserved1;
Word reserved2;
Word reserved3;
Word reserved4;
Word reserved5;
Word reserved6;
#define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h"
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_twolevel_hints_command)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Off Off;
Word cmd;
Word cmdsize;
Off offset; /* offset to the hint table */
Word nhints; /* number of hints */
#define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h"
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_ppc_thread_state)
typedef typename TMachITypes::Addr Addr; typedef typename TMachITypes::Addr Addr;
Addr srr0; /* Instruction address register (PC; entry addr) */ Addr srr0; /* Instruction address register (PC; entry addr) */
@@ -167,12 +242,10 @@ struct Mach_ppc_thread_state
Addr mq; /* MQ register (601 only) */ Addr mq; /* MQ register (601 only) */
Addr vrsave; /* Vector Save Register */ Addr vrsave; /* Vector Save Register */
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes> template <class TMachITypes>
struct Mach_i386_thread_state __packed_struct(Mach_i386_thread_state)
{
typedef typename TMachITypes::Word Word; typedef typename TMachITypes::Word Word;
Word eax, ebx, ecx, edx; Word eax, ebx, ecx, edx;
@@ -181,12 +254,22 @@ struct Mach_i386_thread_state
Word eflags; Word eflags;
Word eip, cs; Word eip, cs;
Word ds, es, fs, gs; Word ds, es, fs, gs;
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes> template <class TMachITypes>
struct Mach_i386_new_thread_state __packed_struct(Mach_AMD64_thread_state)
{ typedef typename TMachITypes::Xword Xword;
Xword rax, rbx, rcx, rdx;
Xword rdi, rsi, rbp, rsp;
Xword r8, r9, r10, r11;
Xword r12, r13, r14, r15;
Xword rip, rflags;
Xword cs, fs, gs;
__packed_struct_end()
template <class TMachITypes>
__packed_struct(Mach_i386_new_thread_state)
typedef typename TMachITypes::Word Word; typedef typename TMachITypes::Word Word;
Word gs, fs, es, ds; Word gs, fs, es, ds;
@@ -194,8 +277,18 @@ struct Mach_i386_new_thread_state
Word ebx, edx, ecx, eax; Word ebx, edx, ecx, eax;
Word eip, cs, efl; Word eip, cs, efl;
Word uesp, ss; Word uesp, ss;
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes>
__packed_struct(Mach_ARM_thread_state)
typedef typename TMachITypes::Word Word;
Word r[13]; // r0-r12
Word sp; // r13
Word lr; // r14
Word pc; // r15
Word cpsr;
__packed_struct_end()
} // namespace N_Mach } // namespace N_Mach
@@ -206,8 +299,7 @@ namespace N_Mach32 {
namespace N_Mach64 { namespace N_Mach64 {
template <class TMachITypes> template <class TMachITypes>
struct Mach_ppc_thread_state64 __packed_struct(Mach_ppc_thread_state64)
{
typedef typename TMachITypes::Word Word; typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Xword Xword; typedef typename TMachITypes::Xword Xword;
@@ -224,8 +316,27 @@ struct Mach_ppc_thread_state64
Xword ctr; /* Count register */ Xword ctr; /* Count register */
Word vrsave; /* Vector Save Register */ Word vrsave; /* Vector Save Register */
} __packed_struct_end()
__attribute_packed;
template <class TMachITypes>
__packed_struct(Mach_routines_command_64)
typedef typename TMachITypes::Word Word;
typedef typename TMachITypes::Addr Addr;
typedef typename TMachITypes::Xword Xword;
Word cmd;
Word cmdsize;
Addr init_address;
Xword init_module;
Xword reserved1;
Xword reserved2;
Xword reserved3;
Xword reserved4;
Xword reserved5;
Xword reserved6;
#define WANT_MACH_SEGMENT_ENUM 1
#include "p_mach_enum.h"
__packed_struct_end()
} // namespace N_Mach64 } // namespace N_Mach64
@@ -251,8 +362,15 @@ struct MachClass_32
typedef N_Mach::Mach_header<MachITypes> Mach_header; typedef N_Mach::Mach_header<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command; typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command; typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state; typedef N_Mach::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state; typedef N_Mach::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
typedef N_Mach::Mach_AMD64_thread_state<MachITypes> Mach_AMD64_thread_state;
typedef N_Mach::Mach_ARM_thread_state<MachITypes> Mach_ARM_thread_state;
static void compileTimeAssertions() { static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions(); BeLePolicy::compileTimeAssertions();
@@ -270,14 +388,25 @@ struct MachClass_64
typedef typename TP::U32 TE32; typedef typename TP::U32 TE32;
typedef typename TP::U64 TE64; typedef typename TP::U64 TE64;
typedef N_Mach::MachITypes<TE32, TE64, TE64, TE64> MachITypes; typedef N_Mach::MachITypes<TE32, TE64, TE64, TE64> MachITypes;
#if (ACC_CC_BORLANDC)
typedef TE64 Addr;
#else
typedef typename MachITypes::Addr Addr;
#endif
// Mach types // Mach types
typedef N_Mach::Mach_header64<MachITypes> Mach_header; typedef N_Mach::Mach_header64<MachITypes> Mach_header;
typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command; typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command; typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
static void compileTimeAssertions() { static void compileTimeAssertions() {
BeLePolicy::compileTimeAssertions(); BeLePolicy::compileTimeAssertions();
COMPILE_TIME_ASSERT(sizeof(Addr) == 8)
} }
}; };
@@ -293,24 +422,56 @@ typedef N_Mach::MachClass_64<N_BELE_CTP::LEPolicy> MachClass_LE64;
// shortcuts // shortcuts
typedef MachClass_Host32::Mach_segment_command Mach32_segment_command; typedef MachClass_Host32::Mach_segment_command Mach32_segment_command;
typedef MachClass_Host32::Mach_section_command Mach32_section_command; typedef MachClass_Host32::Mach_section_command Mach32_section_command;
typedef MachClass_Host32::Mach_symtab_command Mach32_symtab_command;
typedef MachClass_Host32::Mach_dysymtab_command Mach32_dysymtab_command;
typedef MachClass_Host32::Mach_segsplit_info_command Mach32_segsplit_info_command;
typedef MachClass_Host32::Mach_routines_command Mach32_routines_command;
typedef MachClass_Host32::Mach_twolevel_hints_command Mach32_twolevel_hints_command;
typedef MachClass_Host64::Mach_segment_command Mach64_segment_command; typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
typedef MachClass_Host64::Mach_section_command Mach64_section_command; typedef MachClass_Host64::Mach_section_command Mach64_section_command;
typedef MachClass_Host64::Mach_symtab_command Mach64_symtab_command;
typedef MachClass_Host64::Mach_dysymtab_command Mach64_dysymtab_command;
typedef MachClass_Host64::Mach_segsplit_info_command Mach64_segsplit_info_command;
typedef MachClass_Host64::Mach_routines_command Mach64_routines_command;
typedef MachClass_Host64::Mach_twolevel_hints_command Mach64_twolevel_hints_command;
typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command; typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
typedef MachClass_BE32::Mach_section_command MachBE32_section_command; typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
typedef MachClass_BE32::Mach_symtab_command MachBE32_symtab_command;
typedef MachClass_BE32::Mach_dysymtab_command MachBE32_dysymtab_command;
typedef MachClass_BE32::Mach_segsplit_info_command MachBE32_segsplit_info_command;
typedef MachClass_BE32::Mach_routines_command MachBE32_routines_command;
typedef MachClass_BE32::Mach_twolevel_hints_command MachBE32_twolevel_hints_command;
typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command; typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
typedef MachClass_BE64::Mach_section_command MachBE64_section_command; typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
typedef MachClass_BE64::Mach_symtab_command MachBE64_symtab_command;
typedef MachClass_BE64::Mach_dysymtab_command MachBE64_dysymtab_command;
typedef MachClass_BE64::Mach_segsplit_info_command MachBE64_segsplit_info_command;
typedef MachClass_BE64::Mach_routines_command MachBE64_routines_command;
typedef MachClass_BE64::Mach_twolevel_hints_command MachBE64_twolevel_hints_command;
typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command; typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
typedef MachClass_LE32::Mach_section_command MachLE32_section_command; typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
typedef MachClass_LE32::Mach_symtab_command MachLE32_symtab_command;
typedef MachClass_LE32::Mach_dysymtab_command MachLE32_dysymtab_command;
typedef MachClass_LE32::Mach_segsplit_info_command MachLE32_segsplit_info_command;
typedef MachClass_LE32::Mach_routines_command MachLE32_routines_command;
typedef MachClass_LE32::Mach_twolevel_hints_command MachLE32_twolevel_hints_command;
typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command; typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
typedef MachClass_LE64::Mach_section_command MachLE64_section_command; typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
typedef MachClass_LE64::Mach_symtab_command MachLE64_symtab_command;
typedef MachClass_LE64::Mach_dysymtab_command MachLE64_dysymtab_command;
typedef MachClass_LE64::Mach_segsplit_info_command MachLE64_segsplit_info_command;
typedef MachClass_LE64::Mach_routines_command MachLE64_routines_command;
typedef MachClass_LE64::Mach_twolevel_hints_command MachLE64_twolevel_hints_command;
typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state; typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state; typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
typedef MachClass_LE32::Mach_AMD64_thread_state Mach_AMD64_thread_state; // FIXME LE32 vs AMD64
typedef MachClass_LE32::Mach_ARM_thread_state Mach_ARM_thread_state;
#include "p_unix.h" #include "p_unix.h"
@@ -331,9 +492,15 @@ protected:
typedef typename MachClass::Mach_header Mach_header; typedef typename MachClass::Mach_header Mach_header;
typedef typename MachClass::Mach_segment_command Mach_segment_command; typedef typename MachClass::Mach_segment_command Mach_segment_command;
typedef typename MachClass::Mach_section_command Mach_section_command; typedef typename MachClass::Mach_section_command Mach_section_command;
typedef typename MachClass::Mach_symtab_command Mach_symtab_command;
typedef typename MachClass::Mach_dysymtab_command Mach_dysymtab_command;
typedef typename MachClass::Mach_segsplit_info_command Mach_segsplit_info_command;
typedef typename MachClass::Mach_routines_command Mach_routines_command;
typedef typename MachClass::Mach_twolevel_hints_command Mach_twolevel_hints_command;
public: public:
PackMachBase(InputFile *, unsigned cpuid, unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size); PackMachBase(InputFile *, unsigned cpuid, unsigned filetype,
unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
virtual ~PackMachBase(); virtual ~PackMachBase();
virtual int getVersion() const { return 13; } virtual int getVersion() const { return 13; }
virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getCompressionMethods(int method, int level) const;
@@ -344,6 +511,8 @@ public:
virtual void pack3(OutputFile *, Filter &) = 0; // append loader virtual void pack3(OutputFile *, Filter &) = 0; // append loader
virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader virtual void pack4(OutputFile *, Filter &) = 0; // append PackHeader
virtual void pack4dylib(OutputFile *, Filter &, Addr init_address);
virtual void pack1_setup_threado(OutputFile *const fo) = 0; virtual void pack1_setup_threado(OutputFile *const fo) = 0;
virtual void unpack(OutputFile *fo); virtual void unpack(OutputFile *fo);
@@ -366,6 +535,7 @@ protected:
static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb); static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb);
unsigned my_cputype; unsigned my_cputype;
unsigned my_filetype;
unsigned my_thread_flavor; unsigned my_thread_flavor;
unsigned my_thread_state_word_count; unsigned my_thread_state_word_count;
unsigned my_thread_command_size; unsigned my_thread_command_size;
@@ -375,35 +545,35 @@ protected:
unsigned sz_mach_headers; unsigned sz_mach_headers;
Mach_segment_command *rawmseg; // as input, with sections Mach_segment_command *rawmseg; // as input, with sections
Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections
unsigned o_routines_cmd; // file offset to LC_ROUINTES
unsigned prev_init_address;
Mach_header mhdri; Mach_header mhdri;
Mach_header mhdro; Mach_header mhdro;
Mach_segment_command segcmdo; Mach_segment_command segcmdo;
struct b_info { // 12-byte header before each compressed block __packed_struct(b_info) // 12-byte header before each compressed block
TE32 sz_unc; // uncompressed_size TE32 sz_unc; // uncompressed_size
TE32 sz_cpr; // compressed_size TE32 sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm unsigned char b_method; // compression algorithm
unsigned char b_ftid; // filter id unsigned char b_ftid; // filter id
unsigned char b_cto8; // filter parameter unsigned char b_cto8; // filter parameter
unsigned char b_unused; unsigned char b_unused;
} __packed_struct_end()
__attribute_packed;
struct l_info { // 12-byte trailer in header for loader __packed_struct(l_info) // 12-byte trailer in header for loader
TE32 l_checksum; TE32 l_checksum;
LE32 l_magic; LE32 l_magic;
TE16 l_lsize; TE16 l_lsize;
unsigned char l_version; unsigned char l_version;
unsigned char l_format; unsigned char l_format;
} __packed_struct_end()
__attribute_packed;
struct p_info { // 12-byte packed program header __packed_struct(p_info) // 12-byte packed program header
TE32 p_progid; TE32 p_progid;
TE32 p_filesize; TE32 p_filesize;
TE32 p_blocksize; TE32 p_blocksize;
} __packed_struct_end()
__attribute_packed;
struct l_info linfo; struct l_info linfo;
@@ -424,9 +594,7 @@ class PackMachPPC32 : public PackMachBase<MachClass_BE32>
typedef PackMachBase<MachClass_BE32> super; typedef PackMachBase<MachClass_BE32> super;
public: public:
PackMachPPC32(InputFile *f) : super(f, Mach_header::CPU_TYPE_POWERPC, PackMachPPC32(InputFile *f);
Mach_thread_command::PPC_THREAD_STATE,
sizeof(Mach_ppc_thread_state)>>2, sizeof(threado)) { }
virtual int getFormat() const { return UPX_F_MACH_PPC32; } virtual int getFormat() const { return UPX_F_MACH_PPC32; }
virtual const char *getName() const { return "Mach/ppc32"; } virtual const char *getName() const { return "Mach/ppc32"; }
@@ -441,8 +609,7 @@ protected:
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
struct Mach_thread_command __packed_struct(Mach_thread_command)
{
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
BE32 cmdsize; /* total size of this command */ BE32 cmdsize; /* total size of this command */
BE32 flavor; BE32 flavor;
@@ -450,19 +617,33 @@ protected:
Mach_ppc_thread_state state; Mach_ppc_thread_state state;
#define WANT_MACH_THREAD_ENUM #define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h" #include "p_mach_enum.h"
} __packed_struct_end()
__attribute_packed;
Mach_thread_command threado; Mach_thread_command threado;
}; };
class PackDylibPPC32 : public PackMachPPC32
{
typedef PackMachPPC32 super;
public:
PackDylibPPC32(InputFile *f);
virtual int getFormat() const { return UPX_F_DYLIB_PPC32; }
virtual const char *getName() const { return "Dylib/ppc32"; }
virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.dylib"; }
protected:
virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
virtual void buildLoader(const Filter *ft);
};
class PackMachI386 : public PackMachBase<MachClass_LE32> class PackMachI386 : public PackMachBase<MachClass_LE32>
{ {
typedef PackMachBase<MachClass_LE32> super; typedef PackMachBase<MachClass_LE32> super;
public: public:
PackMachI386(InputFile *f) : super(f, Mach_header::CPU_TYPE_I386, PackMachI386(InputFile *f);
(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 int getFormat() const { return UPX_F_MACH_i386; }
virtual const char *getName() const { return "Mach/i386"; } virtual const char *getName() const { return "Mach/i386"; }
@@ -477,8 +658,7 @@ protected:
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
virtual void addStubEntrySections(Filter const *); virtual void addStubEntrySections(Filter const *);
struct Mach_thread_command __packed_struct(Mach_thread_command)
{
LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */ LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
LE32 cmdsize; /* total size of this command */ LE32 cmdsize; /* total size of this command */
LE32 flavor; LE32 flavor;
@@ -486,8 +666,91 @@ protected:
Mach_i386_thread_state state; Mach_i386_thread_state state;
#define WANT_MACH_THREAD_ENUM #define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h" #include "p_mach_enum.h"
} __packed_struct_end()
__attribute_packed;
Mach_thread_command threado;
};
class PackDylibI386 : public PackMachI386
{
typedef PackMachI386 super;
public:
PackDylibI386(InputFile *f);
virtual int getFormat() const { return UPX_F_DYLIB_i386; }
virtual const char *getName() const { return "Dylib/i386"; }
virtual const char *getFullName(const options_t *) const { return "i386-darwin.dylib"; }
protected:
virtual void pack3(OutputFile *, Filter &); // append loader
virtual void pack4(OutputFile *, Filter &); // append PackHeader
virtual void buildLoader(const Filter *ft);
};
class PackMachAMD64 : public PackMachBase<MachClass_LE64>
{
typedef PackMachBase<MachClass_LE64> super;
public:
PackMachAMD64(InputFile *f);
virtual int getFormat() const { return UPX_F_MACH_AMD64; }
virtual const char *getName() const { return "Mach/AMD64"; }
virtual const char *getFullName(const options_t *) const { return "AMD64-darwin.macho"; }
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);
virtual void addStubEntrySections(Filter const *);
__packed_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_AMD64_thread_state state;
#define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h"
__packed_struct_end()
Mach_thread_command threado;
};
class PackMachARMEL : public PackMachBase<MachClass_LE32>
{
typedef PackMachBase<MachClass_LE32> super;
public:
PackMachARMEL(InputFile *f);
virtual int getFormat() const { return UPX_F_MACH_ARMEL; }
virtual const char *getName() const { return "Mach/ARMEL"; }
virtual const char *getFullName(const options_t *) const { return "ARMEL-darwin.macho"; }
protected:
virtual const int *getCompressionMethods(int method, int level) const;
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);
virtual void addStubEntrySections(Filter const *);
__packed_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_ARM_thread_state state;
#define WANT_MACH_THREAD_ENUM
#include "p_mach_enum.h"
__packed_struct_end()
Mach_thread_command threado; Mach_thread_command threado;
}; };
@@ -525,11 +788,11 @@ public:
#endif #endif
enum { N_FAT_ARCH = 5 }; enum { N_FAT_ARCH = 5 };
protected: protected:
struct Fat_head { __packed_struct(Fat_head)
struct Mach_fat_header fat; struct Mach_fat_header fat;
struct Mach_fat_arch arch[N_FAT_ARCH]; struct Mach_fat_arch arch[N_FAT_ARCH];
} __packed_struct_end()
__attribute_packed;
Fat_head fat_head; Fat_head fat_head;
// UI handler // UI handler
+29 -5
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 2007 John F. Reiser Copyright (C) 2007-2009 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -40,11 +40,19 @@
}; };
enum { // cputype enum { // cputype
CPU_TYPE_I386 = 7, CPU_TYPE_I386 = 7,
CPU_TYPE_X86_64 = 0x01000007,
CPU_TYPE_ARM = 12,
CPU_TYPE_POWERPC = 0x00000012, CPU_TYPE_POWERPC = 0x00000012,
CPU_TYPE_POWERPC64 = 0x01000012 CPU_TYPE_POWERPC64 = 0x01000012
}; };
enum { // cpusubtype
CPU_SUBTYPE_ARM_ALL = 0,
CPU_SUBTYPE_ARM_V4T = 5,
CPU_SUBTYPE_ARM_V6 = 6
};
enum { // filetype enum { // filetype
MH_EXECUTE = 2 MH_EXECUTE = 2,
MH_DYLIB = 6
}; };
enum { // flags enum { // flags
MH_NOUNDEFS = 1 MH_NOUNDEFS = 1
@@ -55,10 +63,23 @@
#undef WANT_MACH_SEGMENT_ENUM #undef WANT_MACH_SEGMENT_ENUM
enum { // cmd enum { // cmd
LC_SEGMENT = 0x1, LC_SEGMENT = 0x1,
LC_SYMTAB = 0x2,
LC_THREAD = 0x4, LC_THREAD = 0x4,
LC_UNIXTHREAD = 0x5, LC_UNIXTHREAD = 0x5,
LC_DYSYMTAB = 0xb,
LC_LOAD_DYLIB = 0xc,
LC_ID_DYLIB = 0xd,
LC_LOAD_DYLINKER = 0xe, LC_LOAD_DYLINKER = 0xe,
LC_SEGMENT_64 = 0x19 LC_ROUTINES = 0x11,
LC_TWOLEVEL_HINTS= 0x16,
LC_SEGMENT_64 = 0x19,
LC_ROUTINES_64 = 0x1a,
LC_UUID = 0x1b,
LC_RPATH = 0x1c,
LC_CODE_SIGNATURE = 0x1d,
LC_SEGMENT_SPLIT_INFO = 0x1e,
LC_REEXPORT_DYLIB = 0x1f,
LC_REQ_DYLD = 0x80000000 // OR'ed ==> must not ignore
}; };
enum { // maxprot enum { // maxprot
VM_PROT_READ = 1, VM_PROT_READ = 1,
@@ -97,8 +118,11 @@
#undef WANT_MACH_THREAD_ENUM #undef WANT_MACH_THREAD_ENUM
enum { // thread flavor enum { // thread flavor
PPC_THREAD_STATE = 1, PPC_THREAD_STATE = 1,
i386_THREAD_STATE = 1, PPC_THREAD_STATE64 = 5,
i386_OLD_THREAD_STATE = -1 x86_THREAD_STATE32 = 1,
x86_THREAD_STATE64 = 4,
i386_OLD_THREAD_STATE = -1,
ARM_THREAD_STATE = 1
}; };
#endif /*}*/ #endif /*}*/
+6 -6
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2002-2008 Jens Medoch Copyright (C) 2002-2009 Jens Medoch
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -127,8 +127,8 @@ int PackPs1::readFileHeader()
{ {
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(&ih, sizeof(ih)); fi->readx(&ih, sizeof(ih));
if (memcmp(&ih.id, "PS-X EXE", 8) != 0 && if (memcmp(&ih.id[0], "PS-X EXE", 8) != 0 &&
memcmp(&ih.id, "EXE X-SP", 8) != 0) memcmp(&ih.id[0], "EXE X-SP", 8) != 0)
return 0; return 0;
if (ih.text != 0 || ih.data != 0) if (ih.text != 0 || ih.data != 0)
return 0; return 0;
@@ -433,7 +433,7 @@ bool PackPs1::findBssSection()
reg = REG1(op); reg = REG1(op);
for (; i >= 0; i--) for (; i >= 0; i--)
{ {
bss_nfo *p = (bss_nfo *)&p1[i]; bss_nfo *p = (bss_nfo *)(void *)&p1[i];
unsigned short op1 = p->op1, op2 = p->op2; unsigned short op1 = p->op1, op2 = p->op2;
// check for la (x),bss_start // check for la (x),bss_start
+11 -19
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
Copyright (C) 2002-2008 Jens Medoch Copyright (C) 2002-2009 Jens Medoch
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -67,8 +67,7 @@ protected:
virtual int readFileHeader(); virtual int readFileHeader();
virtual bool checkFileHeader(); virtual bool checkFileHeader();
struct ps1_exe_t __packed_struct(ps1_exe_t)
{
// ident string // ident string
char id[8]; char id[8];
// is NULL // is NULL
@@ -91,33 +90,26 @@ protected:
char origin[60]; char origin[60];
// backup of the original header (epc - is_len) // backup of the original header (epc - is_len)
// id & the upx header ... // id & the upx header ...
} __packed_struct_end()
__attribute_packed;
// for unpack // for unpack
struct ps1_exe_hb_t __packed_struct(ps1_exe_hb_t)
{
LE32 ih_bkup[10]; LE32 ih_bkup[10];
// plus checksum for the backup // plus checksum for the backup
LE32 ih_csum; LE32 ih_csum;
} __packed_struct_end()
__attribute_packed;
struct ps1_exe_chb_t __packed_struct(ps1_exe_chb_t)
{
unsigned char id; unsigned char id;
unsigned char len; unsigned char len;
LE16 ih_csum; LE16 ih_csum;
unsigned char ih_bkup; unsigned char ih_bkup;
} __packed_struct_end()
__attribute_packed;
struct bss_nfo __packed_struct(bss_nfo)
{
LE16 hi1, op1, lo1, op2; LE16 hi1, op1, lo1, op2;
LE16 hi2, op3, lo2, op4; LE16 hi2, op3, lo2, op4;
} __packed_struct_end()
__attribute_packed;
ps1_exe_t ih, oh; ps1_exe_t ih, oh;
ps1_exe_hb_t bh; ps1_exe_hb_t bh;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+4 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -62,8 +62,7 @@ protected:
virtual int readFileHeader(); virtual int readFileHeader();
virtual bool checkFileHeader(); virtual bool checkFileHeader();
struct tos_header_t __packed_struct(tos_header_t)
{
BE16 fh_magic; BE16 fh_magic;
BE32 fh_text; BE32 fh_text;
BE32 fh_data; BE32 fh_data;
@@ -72,8 +71,7 @@ protected:
BE32 fh_reserved; BE32 fh_reserved;
BE32 fh_flag; BE32 fh_flag;
BE16 fh_reloc; BE16 fh_reloc;
} __packed_struct_end()
__attribute_packed;
tos_header_t ih, oh; tos_header_t ih, oh;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+23 -31
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -92,30 +92,28 @@ protected:
unsigned b_len; // total length of b_info blocks unsigned b_len; // total length of b_info blocks
// must agree with stub/linux.hh // must agree with stub/linux.hh
struct b_info { // 12-byte header before each compressed block __packed_struct(b_info) // 12-byte header before each compressed block
unsigned sz_unc; // uncompressed_size unsigned sz_unc; // uncompressed_size
unsigned sz_cpr; // compressed_size unsigned sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm unsigned char b_method; // compression algorithm
unsigned char b_ftid; // filter id unsigned char b_ftid; // filter id
unsigned char b_cto8; // filter parameter unsigned char b_cto8; // filter parameter
unsigned char b_unused; unsigned char b_unused;
} __packed_struct_end()
__attribute_packed;
struct l_info { // 12-byte trailer in header for loader __packed_struct(l_info) // 12-byte trailer in header for loader
LE32 l_checksum; LE32 l_checksum;
LE32 l_magic; LE32 l_magic;
LE16 l_lsize; LE16 l_lsize;
unsigned char l_version; unsigned char l_version;
unsigned char l_format; unsigned char l_format;
} __packed_struct_end()
__attribute_packed;
struct p_info { // 12-byte packed program header __packed_struct(p_info) // 12-byte packed program header
unsigned p_progid; unsigned p_progid;
unsigned p_filesize; unsigned p_filesize;
unsigned p_blocksize; unsigned p_blocksize;
} __packed_struct_end()
__attribute_packed;
struct l_info linfo; struct l_info linfo;
@@ -135,31 +133,28 @@ protected:
PackUnixBe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; } PackUnixBe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; }
// must agree with stub/linux.hh // must agree with stub/linux.hh
struct b_info { // 12-byte header before each compressed block __packed_struct(b_info) // 12-byte header before each compressed block
BE32 sz_unc; // uncompressed_size BE32 sz_unc; // uncompressed_size
BE32 sz_cpr; // compressed_size BE32 sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm unsigned char b_method; // compression algorithm
unsigned char b_ftid; // filter id unsigned char b_ftid; // filter id
unsigned char b_cto8; // filter parameter unsigned char b_cto8; // filter parameter
unsigned char b_unused; unsigned char b_unused;
} __packed_struct_end()
__attribute_packed;
struct l_info { // 12-byte trailer in header for loader __packed_struct(l_info) // 12-byte trailer in header for loader
BE32 l_checksum; BE32 l_checksum;
BE32 l_magic; BE32 l_magic;
BE16 l_lsize; BE16 l_lsize;
unsigned char l_version; unsigned char l_version;
unsigned char l_format; unsigned char l_format;
} __packed_struct_end()
__attribute_packed;
struct p_info { // 12-byte packed program header __packed_struct(p_info) // 12-byte packed program header
BE32 p_progid; BE32 p_progid;
BE32 p_filesize; BE32 p_filesize;
BE32 p_blocksize; BE32 p_blocksize;
} __packed_struct_end()
__attribute_packed;
}; };
@@ -170,31 +165,28 @@ protected:
PackUnixLe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; } PackUnixLe32(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
// must agree with stub/linux.hh // must agree with stub/linux.hh
struct b_info { // 12-byte header before each compressed block __packed_struct(b_info) // 12-byte header before each compressed block
LE32 sz_unc; // uncompressed_size LE32 sz_unc; // uncompressed_size
LE32 sz_cpr; // compressed_size LE32 sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm unsigned char b_method; // compression algorithm
unsigned char b_ftid; // filter id unsigned char b_ftid; // filter id
unsigned char b_cto8; // filter parameter unsigned char b_cto8; // filter parameter
unsigned char b_unused; unsigned char b_unused;
} __packed_struct_end()
__attribute_packed;
struct l_info { // 12-byte trailer in header for loader __packed_struct(l_info) // 12-byte trailer in header for loader
LE32 l_checksum; LE32 l_checksum;
LE32 l_magic; LE32 l_magic;
LE16 l_lsize; LE16 l_lsize;
unsigned char l_version; unsigned char l_version;
unsigned char l_format; unsigned char l_format;
} __packed_struct_end()
__attribute_packed;
struct p_info { // 12-byte packed program header __packed_struct(p_info) // 12-byte packed program header
LE32 p_progid; LE32 p_progid;
LE32 p_filesize; LE32 p_filesize;
LE32 p_blocksize; LE32 p_blocksize;
} __packed_struct_end()
__attribute_packed;
}; };
+7 -8
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 2004-2008 John Reiser Copyright (C) 2004-2009 John Reiser
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -64,7 +64,7 @@ PackVmlinuxBase<T>::PackVmlinuxBase(InputFile *f,
n_ptload(0), phdri(NULL), shdri(NULL), shstrtab(NULL) n_ptload(0), phdri(NULL), shdri(NULL), shstrtab(NULL)
{ {
ElfClass::compileTimeAssertions(); ElfClass::compileTimeAssertions();
bele = N_BELE_CTP::getRTP<BeLePolicy>(); bele = N_BELE_CTP::getRTP((const BeLePolicy*) NULL);
} }
template <class T> template <class T>
@@ -301,7 +301,7 @@ void PackVmlinuxBase<T>::pack(OutputFile *fo)
if (UPX_E_OK!=r || len_unc<=len_cpr) // FIXME: allow no compression if (UPX_E_OK!=r || len_unc<=len_cpr) // FIXME: allow no compression
throwInternalError("Ehdr compression failed"); throwInternalError("Ehdr compression failed");
struct b_info { // 12-byte header before each compressed block __packed_struct(b_info) // 12-byte header before each compressed block
unsigned sz_unc; // uncompressed_size unsigned sz_unc; // uncompressed_size
unsigned sz_cpr; // compressed_size unsigned sz_cpr; // compressed_size
unsigned char b_method; // compression algorithm unsigned char b_method; // compression algorithm
@@ -309,8 +309,7 @@ void PackVmlinuxBase<T>::pack(OutputFile *fo)
unsigned char b_cto8; // filter parameter unsigned char b_cto8; // filter parameter
unsigned char b_unused; // FIXME: !=0 for partial-block unfilter unsigned char b_unused; // FIXME: !=0 for partial-block unfilter
// unsigned f_offset, f_len; // only if partial-block unfilter // unsigned f_offset, f_len; // only if partial-block unfilter
} __packed_struct_end()
__attribute_packed;
struct b_info hdr_info; struct b_info hdr_info;
set_be32(&hdr_info.sz_unc, len_unc); set_be32(&hdr_info.sz_unc, len_unc);
@@ -628,7 +627,7 @@ void prep_kernel(unsigned long a1, unsigned long a2)
fo->seek(0, SEEK_SET); fo->seek(0, SEEK_SET);
fo->write(&ehdro, sizeof(ehdro)); fo->write(&ehdro, sizeof(ehdro));
fo->write(&shdro, sizeof(shdro)); fo->write(&shdro[0], sizeof(shdro));
if (Ehdr::EM_PPC==my_e_machine) { if (Ehdr::EM_PPC==my_e_machine) {
fo->seek(sizeof(unsigned), SEEK_CUR); fo->seek(sizeof(unsigned), SEEK_CUR);
set_be32(&ppc32_extra, ppc32_extra - 2*sizeof(unsigned) + txt_c_len); set_be32(&ppc32_extra, ppc32_extra - 2*sizeof(unsigned) + txt_c_len);
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+433 -17
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -28,6 +28,7 @@
#include "conf.h" #include "conf.h"
#include "p_elf.h"
#include "file.h" #include "file.h"
#include "filter.h" #include "filter.h"
#include "packer.h" #include "packer.h"
@@ -52,9 +53,10 @@ static const unsigned bzimage_offset = 0x100000;
PackVmlinuzI386::PackVmlinuzI386(InputFile *f) : PackVmlinuzI386::PackVmlinuzI386(InputFile *f) :
super(f), physical_start(0x100000), page_offset(0), config_physical_align(0) super(f), physical_start(0x100000), page_offset(0), config_physical_align(0)
, filter_len(0)
{ {
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x218); COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x250);
} }
@@ -82,6 +84,13 @@ const int *PackBvmlinuzI386::getFilters() const
return filters; return filters;
} }
int PackVmlinuzI386::getStrategy(Filter &/*ft*/)
{
// If user specified the filter, then use it (-2==filter_strategy).
// Else try the first two filters, and pick the better (2==filter_strategy).
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
}
bool PackVmlinuzI386::canPack() bool PackVmlinuzI386::canPack()
{ {
@@ -95,8 +104,6 @@ bool PackVmlinuzI386::canPack()
int PackVmlinuzI386::readFileHeader() int PackVmlinuzI386::readFileHeader()
{ {
boot_sect_t h;
setup_size = 0; setup_size = 0;
fi->readx(&h, sizeof(h)); fi->readx(&h, sizeof(h));
@@ -160,6 +167,10 @@ int PackVmlinuzI386::decompressKernel()
unsigned cpa_0 = 0; unsigned cpa_0 = 0;
unsigned cpa_1 = 0; unsigned cpa_1 = 0;
int j; int j;
if (0x205<=h.version) {
cpa_0 = h.kernel_alignment;
cpa_1 = 0u - cpa_0;
} else
for ((p = &obuf[setup_size]), (j= 0); j < 0x200; ++j, ++p) { for ((p = &obuf[setup_size]), (j= 0); j < 0x200; ++j, ++p) {
if (0==memcmp("\x89\xeb\x81\xc3", p, 4) if (0==memcmp("\x89\xeb\x81\xc3", p, 4)
&& 0==memcmp("\x81\xe3", 8+ p, 2)) { && 0==memcmp("\x81\xe3", 8+ p, 2)) {
@@ -225,14 +236,18 @@ int PackVmlinuzI386::decompressKernel()
checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024)); checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024));
for (int gzoff = setup_size; gzoff < file_size; gzoff++) int gzoff = setup_size;
if (0x208<=h.version) {
gzoff += h.payload_offset;
}
for (; gzoff < file_size; gzoff++)
{ {
// find gzip header (2 bytes magic + 1 byte method "deflated") // find gzip header (2 bytes magic + 1 byte method "deflated")
int off = find(obuf + gzoff, file_size - gzoff, "\x1F\x8B\x08", 3); int off = find(obuf + gzoff, file_size - gzoff, "\x1F\x8B\x08", 3);
if (off < 0) if (off < 0)
break; break;
gzoff += off; gzoff += off;
const int gzlen = file_size - gzoff; const int gzlen = (h.version < 0x208) ? (file_size - gzoff) : h.payload_length;
if (gzlen < 256) if (gzlen < 256)
break; break;
// check gzip flag byte // check gzip flag byte
@@ -281,6 +296,49 @@ int PackVmlinuzI386::decompressKernel()
if (klen <= gzlen) if (klen <= gzlen)
continue; continue;
if (0x208<=h.version && 0==memcmp("\177ELF", ibuf, 4)) {
// Full ELF in theory; for now, try to handle as .bin at physical_start.
// Check for PT_LOAD.p_paddr being ascending and adjacent.
Elf_LE32_Ehdr const *const ehdr = (Elf_LE32_Ehdr const *)(void const *)ibuf;
Elf_LE32_Phdr const *phdr = (Elf_LE32_Phdr const *)(ehdr->e_phoff + (char const *)ehdr);
Elf_LE32_Shdr const *shdr = (Elf_LE32_Shdr const *)(ehdr->e_shoff + (char const *)ehdr);
unsigned hi_paddr = 0, lo_paddr = 0;
unsigned delta_off = 0;
for (unsigned j=0; j < ehdr->e_phnum; ++j, ++phdr) {
if (phdr->PT_LOAD==phdr->p_type) {
unsigned step = (hi_paddr + phdr->p_align - 1) & ~(phdr->p_align - 1);
if (0==hi_paddr) { // first PT_LOAD
if (physical_start!=phdr->p_paddr) {
return 0;
}
delta_off = phdr->p_paddr - phdr->p_offset;
lo_paddr = phdr->p_paddr;
hi_paddr = phdr->p_filesz + phdr->p_paddr;
}
else if (step==phdr->p_paddr
&& delta_off==(phdr->p_paddr - phdr->p_offset)) {
hi_paddr = phdr->p_filesz + phdr->p_paddr;
}
else {
return 0; // Not equivalent to a .bin. Too complex for now.
}
}
}
// FIXME: ascending order is only a convention; might need sorting.
for (unsigned j=1; j < ehdr->e_shnum; ++j) {
if (shdr->SHT_PROGBITS==shdr->sh_type) { // SHT_REL might be intermixed
if (shdr->SHF_EXECINSTR & shdr[j].sh_flags) {
filter_len += shdr[j].sh_size; // FIXME: include sh_addralign
}
else {
break;
}
}
}
memmove(ibuf, (lo_paddr - delta_off) + ibuf, hi_paddr - lo_paddr); // FIXME: set_size
// FIXME: .bss ? Apparently handled by head.S
}
if (opt->force > 0) if (opt->force > 0)
return klen; return klen;
@@ -402,7 +460,7 @@ void PackVmlinuzI386::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression // limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
compressWithFilters(&ft, 512, &cconf); compressWithFilters(&ft, 512, &cconf, getStrategy(ft));
const unsigned lsize = getLoaderSize(); const unsigned lsize = getLoaderSize();
@@ -419,6 +477,7 @@ void PackVmlinuzI386::pack(OutputFile *fo)
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf); boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16u) / 16; bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16u) / 16;
bs->payload_length = ph.c_len;
fo->write(setup_buf, setup_buf.getSize()); fo->write(setup_buf, setup_buf.getSize());
fo->write(loader, lsize); fo->write(loader, lsize);
@@ -448,7 +507,7 @@ void PackBvmlinuzI386::buildLoader(const Filter *ft)
initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz)); initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz));
if (0!=page_offset) { // relocatable kernel if (0!=page_offset) { // relocatable kernel
assert(0==ft->id || 0x40==(0xf0 & ft->id)); // others assume fixed buffer address assert(0==ft->id || 0x40==(0xf0 & ft->id)); // others assume fixed buffer address
addLoader("LINUZ000,LINUZVGA,LINUZ101,LINUZ110", addLoader("LINUZ000,LINUZ001,LINUZVGA,LINUZ101,LINUZ110",
((0!=config_physical_align) ? "LINUZ120" : "LINUZ130"), ((0!=config_physical_align) ? "LINUZ120" : "LINUZ130"),
"LINUZ140,LZCUTPOI,LINUZ141", "LINUZ140,LZCUTPOI,LINUZ141",
(ft->id ? "LINUZ145" : ""), (ft->id ? "LINUZ145" : ""),
@@ -456,7 +515,7 @@ void PackBvmlinuzI386::buildLoader(const Filter *ft)
NULL); NULL);
} }
else { else {
addLoader("LINUZ000,LINUZVGA,LINUZ001", addLoader("LINUZ000,LINUZ001,LINUZVGA,LINUZ005",
ph.first_offset_found == 1 ? "LINUZ010" : "", ph.first_offset_found == 1 ? "LINUZ010" : "",
(0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""), (0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
"LBZIMAGE,IDENTSTR", "LBZIMAGE,IDENTSTR",
@@ -511,17 +570,17 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
// prepare filter // prepare filter
Filter ft(ph.level); Filter ft(ph.level);
ft.buf_len = ph.u_len; ft.buf_len = (filter_len ? filter_len : (ph.u_len * 3)/5);
// May 2008: 3/5 is heuristic to cover most .text but avoid non-instructions.
// Otherwise "call trick" filter cannot find a free marker byte,
// especially when it searches over tables of data.
ft.addvalue = 0; // The destination buffer might be relocated at runtime. ft.addvalue = 0; // The destination buffer might be relocated at runtime.
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression // LINUZ001 allows most of low memory as stack for Bvmlinuz
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack cconf.conf_lzma.max_num_probs = (0x90000 - 0x10000)>>1; // ushort: 512 KiB stack
// FIXME: new stub allows most of low memory as stack for Bvmlinuz ? compressWithFilters(&ft, 512, &cconf, getStrategy(ft));
//cconf.conf_lzma.max_num_probs = (0x99000 - 0x10250)>>1; // ushort: 560560 stack
compressWithFilters(&ft, 512, &cconf);
// align everything to dword boundary - it is easier to handle // align everything to dword boundary - it is easier to handle
unsigned c_len = ph.c_len; unsigned c_len = ph.c_len;
@@ -652,6 +711,363 @@ void PackVmlinuzI386::unpack(OutputFile *fo)
} }
PackVmlinuzARMEL::PackVmlinuzARMEL(InputFile *f) :
super(f), setup_size(0), filter_len(0)
{
bele = &N_BELE_RTP::le_policy;
}
const int *PackVmlinuzARMEL::getCompressionMethods(int method, int level) const
{
return Packer::getDefaultCompressionMethods_8(method, level);
}
const int *PackVmlinuzARMEL::getFilters() const
{
static const int f50[] = { 0x50, FT_END };
return f50;
}
int PackVmlinuzARMEL::getStrategy(Filter &/*ft*/)
{
// If user specified the filter, then use it (-2==filter_strategy).
// Else try the first two filters, and pick the better (2==filter_strategy).
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
}
bool PackVmlinuzARMEL::canPack()
{
return readFileHeader() == getFormat();
}
int PackVmlinuzARMEL::readFileHeader()
{
unsigned int hdr[8];
fi->readx(hdr, sizeof(hdr));
for (int j=0; j < 8; ++j) {
if (0xe1a00000!=get_te32(&hdr[j])) {
return 0;
}
}
return UPX_F_VMLINUZ_ARMEL;
}
int PackVmlinuzARMEL::decompressKernel()
{
// read whole kernel image
obuf.alloc(file_size);
fi->seek(0, SEEK_SET);
fi->readx(obuf, file_size);
//checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024));
// Find head.S:
// bl decompress_kernel # 0xeb......
// b call_kernel # 0xea......
//LC0: .word LC0 # self!
unsigned decompress_kernel = 0;
unsigned caller1 = 0;
unsigned caller2 = 0;
unsigned got_start = 0;
unsigned got_end = 0;
for (unsigned j = 0; j < 0x400; j+=4) {
unsigned w;
if (j!=get_te32(j + obuf)) {
continue;
}
if (0xea000000!=(0xff000000& get_te32(j - 4 + obuf))
|| 0xeb000000!=(0xff000000&(w= get_te32(j - 8 + obuf))) ) {
continue;
}
caller1 = j - 8;
decompress_kernel = ((0x00ffffff & w)<<2) + 8+ caller1;
for (unsigned k = 12; k<=128; k+=4) {
w = get_te32(j - k + obuf);
if (0xeb000000==(0xff000000 & w)
&& decompress_kernel==(((0x00ffffff & w)<<2) + 8+ j - k) ) {
caller2 = j - k;
break;
}
}
got_start = get_te32(5*4 + j + obuf);
got_end = get_te32(6*4 + j + obuf);
#if 0 /*{*/
printf("decompress_kernel=0x%x got_start=0x%x got_end=0x%x\n",
decompress_kernel, got_start, got_end);
#endif /*}*/
break;
}
if (0==decompress_kernel) {
return 0;
}
// Find first subroutine that is called by decompress_kernel,
// which we will consider to be the start of the gunzip module
// and the end of the non-gunzip modules.
for (unsigned j = decompress_kernel; j < (unsigned)file_size; j+=4) {
unsigned w = get_te32(j + obuf);
if (0xeb800000==(0xff800000 & w)) {
setup_size = 8+ ((0xff000000 | w)<<2) + j;
// Move the GlobalOffsetTable.
for (unsigned k = got_start; k < got_end; k+=4) {
w = get_te32(k + obuf);
// FIXME: must relocate w
set_te32(k - got_start + setup_size + obuf, w);
}
setup_size += got_end - got_start;
set_te32(&obuf[caller1], 0xeb000000 |
(0x00ffffff & ((setup_size - (8+ caller1))>>2)) );
set_te32(&obuf[caller2], 0xeb000000 |
(0x00ffffff & ((setup_size - (8+ caller2))>>2)) );
break;
}
}
for (int gzoff = 0; gzoff < 0x4000; gzoff+=4) {
// find gzip header (2 bytes magic + 1 byte method "deflated")
int off = find(obuf + gzoff, file_size - gzoff, "\x1F\x8B\x08", 3);
if (off < 0 || 0!=(3u & off))
break; // not found, or not word-aligned
gzoff += off;
const int gzlen = file_size - gzoff;
if (gzlen < 256)
break;
// check gzip flag byte
unsigned char flags = obuf[gzoff + 3];
if ((flags & 0xe0) != 0) // reserved bits set
continue;
//printf("found gzip header at offset %d\n", gzoff);
// try to decompress
int klen;
int fd;
off_t fd_pos;
for (;;)
{
klen = -1;
fd = -1;
fd_pos = -1;
// open
fi->seek(gzoff, SEEK_SET);
fd = dup(fi->getFd());
if (fd < 0)
break;
gzFile zf = gzdopen(fd, "rb");
if (zf == NULL)
break;
// estimate gzip-decompressed kernel size & alloc buffer
if (ibuf.getSize() == 0)
ibuf.alloc(gzlen * 3);
// decompress
klen = gzread(zf, ibuf, ibuf.getSize());
fd_pos = lseek(fd, 0, SEEK_CUR);
gzclose(zf);
fd = -1;
if (klen != (int)ibuf.getSize())
break;
// realloc and try again
unsigned const s = ibuf.getSize();
ibuf.dealloc();
ibuf.alloc(3 * s / 2);
}
if (fd >= 0)
(void) close(fd);
if (klen <= 0)
continue;
if (klen <= gzlen)
continue;
if (opt->force > 0)
return klen;
// some checks
if (fd_pos != file_size) {
//printf("fd_pos: %ld, file_size: %ld\n", (long)fd_pos, (long)file_size);
}
//head_ok:
// FIXME: more checks for special magic bytes in ibuf ???
// FIXME: more checks for kernel architecture ???
return klen;
}
return 0;
}
void PackVmlinuzARMEL::readKernel()
{
int klen = decompressKernel();
if (klen <= 0)
throwCantPack("kernel decompression failed");
//OutputFile::dump("kernel.img", ibuf, klen);
// copy the setup boot code
setup_buf.alloc(setup_size);
memcpy(setup_buf, obuf, setup_size);
//OutputFile::dump("setup.img", setup_buf, setup_size);
obuf.dealloc();
obuf.allocForCompression(klen);
ph.u_len = klen;
ph.filter = 0;
}
Linker* PackVmlinuzARMEL::newLinker() const
{
return new ElfLinkerArmLE;
}
static const
#include "stub/arm-linux.kernel.vmlinux.h"
static const
#include "stub/armel-linux.kernel.vmlinuz-head.h"
void PackVmlinuzARMEL::buildLoader(const Filter *ft)
{
// prepare loader; same as vmlinux (with 'x')
initLoader(stub_arm_linux_kernel_vmlinux, sizeof(stub_arm_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",
(opt->small ? "LZMA_DEC10" : "LZMA_DEC20"), "LZMA_DEC30", NULL);
else throwBadLoader();
addLoader("IDENTSTR,UPX1HEAD", NULL);
// To debug (2008-09-14):
// Build gdb-6.8-21.fc9.src.rpm; ./configure --target=arm-none-elf; make
// Contains the fix for http://bugzilla.redhat.com/show_bug.cgi?id=436037
// Install qemu-0.9.1-6.fc9.i386.rpm
// qemu-system-arm -s -S -kernel <file> -nographic
// (gdb) target remote localhost:1234
// A very small boot loader runs at pc=0x0; the kernel is at 0x10000 (64KiB).
}
void PackVmlinuzARMEL::defineDecompressorSymbols()
{
super::defineDecompressorSymbols();
linker->defineSymbol( "COMPRESSED_LENGTH", ph.c_len);
linker->defineSymbol("UNCOMPRESSED_LENGTH", ph.u_len);
linker->defineSymbol("METHOD", ph.method);
}
unsigned PackVmlinuzARMEL::write_vmlinuz_head(OutputFile *const fo)
{ // First word from vmlinuz-head.S
fo->write(&stub_armel_linux_kernel_vmlinuz_head[0], 4);
// Second word
LE32 tmp_u32;
unsigned const t = (0xff000000 &
get_te32(&stub_armel_linux_kernel_vmlinuz_head[4]))
| (0x00ffffff & (0u - 1 + ((3+ ph.c_len)>>2)));
tmp_u32 = t;
fo->write((void const *)&tmp_u32, 4);
return sizeof(stub_armel_linux_kernel_vmlinuz_head);
}
void PackVmlinuzARMEL::pack(OutputFile *fo)
{
readKernel();
// prepare filter
Filter ft(ph.level);
ft.buf_len = ph.u_len;
ft.addvalue = 0;
// compress
upx_compress_config_t cconf; cconf.reset();
// limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 5); // ushort: 52,844 byte stack
compressWithFilters(&ft, 512, &cconf, getStrategy(ft));
const unsigned lsize = getLoaderSize();
defineDecompressorSymbols();
defineFilterSymbols(&ft);
relocateLoader();
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
// boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
// bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16u) / 16;
// bs->payload_length = ph.c_len;
fo->write(setup_buf, setup_buf.getSize());
write_vmlinuz_head(fo);
fo->write(obuf, ph.c_len);
unsigned const zero = 0;
fo->write((void const *)&zero, 3u & (0u - ph.c_len));
fo->write(loader, lsize);
#if 0
printf("%-13s: setup : %8ld bytes\n", getName(), (long) setup_buf.getSize());
printf("%-13s: loader : %8ld bytes\n", getName(), (long) lsize);
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
#endif
// verify
verifyOverlappingDecompression();
// finally check the compression ratio
if (!checkFinalCompressionRatio(fo))
throwNotCompressible();
}
int PackVmlinuzARMEL::canUnpack()
{
if (readFileHeader() != getFormat())
return false;
fi->seek(setup_size, SEEK_SET);
return readPackHeader(1024) ? 1 : -1;
}
void PackVmlinuzARMEL::unpack(OutputFile *fo)
{
// no uncompression support for this format, so that
// it is possible to remove the original deflate code (>10 KiB)
// FIXME: but we could write the uncompressed "vmlinux" image
ibuf.alloc(ph.c_len);
obuf.allocForUncompression(ph.u_len);
fi->seek(setup_size + ph.buf_offset + ph.getPackHeaderSize(), SEEK_SET);
fi->readx(ibuf, ph.c_len);
// decompress
decompress(ibuf, obuf);
// unfilter
Filter ft(ph.level);
ft.init(ph.filter, 0);
ft.cto = (unsigned char) ph.filter_cto;
ft.unfilter(obuf, ph.u_len);
// write decompressed file
if (fo)
{
throwCantUnpack("build a new kernel instead :-)");
//fo->write(obuf, ph.u_len);
}
}
/* /*
vi:ts=4:et vi:ts=4:et
*/ */
+61 -8
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -45,6 +45,7 @@ public:
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinuz"; } virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinuz"; }
virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
virtual int getStrategy(Filter &);
virtual void pack(OutputFile *fo); virtual void pack(OutputFile *fo);
virtual void unpack(OutputFile *fo); virtual void unpack(OutputFile *fo);
@@ -63,8 +64,7 @@ protected:
// virtual upx_byte *getLoader() const; // virtual upx_byte *getLoader() const;
// virtual int getLoaderSize() const; // virtual int getLoaderSize() const;
struct boot_sect_t __packed_struct(boot_sect_t)
{
char _[0x1f1]; char _[0x1f1];
unsigned char setup_sects; unsigned char setup_sects;
char __[2]; char __[2];
@@ -79,17 +79,24 @@ protected:
unsigned char load_flags; unsigned char load_flags;
char ______[2]; char ______[2];
LE32 code32_start; LE32 code32_start;
char _7[0x230 - (0x214 + 4)];
LE32 kernel_alignment;
char relocatable_kernel;
char _8[0x248 - (0x234 + 1)];
LE32 payload_offset;
LE32 payload_length;
// some more uninteresting fields here ... // some more uninteresting fields here ...
// see /usr/src/linux/Documentation/i386/zero-page.txt // see /usr/src/linux/Documentation/i386/boot.txt
} __packed_struct_end()
__attribute_packed;
boot_sect_t h;
MemBuffer setup_buf; MemBuffer setup_buf;
int setup_size; int setup_size;
unsigned physical_start; unsigned physical_start;
unsigned page_offset; unsigned page_offset;
unsigned config_physical_align; unsigned config_physical_align;
unsigned filter_len;
}; };
@@ -142,6 +149,52 @@ protected:
}; };
/*************************************************************************
// vmlinuz/armel (gzip compressed Linux kernel image)
**************************************************************************/
class PackVmlinuzARMEL : public Packer
{
typedef Packer super;
public:
PackVmlinuzARMEL(InputFile *f);
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_VMLINUZ_ARMEL; }
virtual const char *getName() const { return "vmlinuz/armel"; }
virtual const char *getFullName(const options_t *) const { return "armel-linux.kernel.vmlinuz"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
virtual int getStrategy(Filter &);
virtual void pack(OutputFile *fo);
virtual void unpack(OutputFile *fo);
virtual bool canPack();
virtual int canUnpack();
protected:
virtual int readFileHeader();
virtual int decompressKernel();
virtual void readKernel();
virtual void buildLoader(const Filter *ft);
virtual unsigned write_vmlinuz_head(OutputFile *const fo);
virtual void defineDecompressorSymbols();
virtual Linker* newLinker() const;
// virtual upx_byte *getLoader() const;
// virtual int getLoaderSize() const;
MemBuffer setup_buf;
int setup_size;
// unsigned physical_start;
// unsigned page_offset;
// unsigned config_physical_align;
unsigned filter_len;
};
#endif /* already included */ #endif /* already included */
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+6 -8
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -164,7 +164,7 @@ int PackW32Pe::readFileHeader()
char buf[6]; char buf[6];
fi->seek(0x200, SEEK_SET); fi->seek(0x200, SEEK_SET);
fi->readx(buf, 6); fi->readx(buf, 6);
isrtm = memcmp(&buf, "32STUB" ,6) == 0; isrtm = memcmp(buf, "32STUB" ,6) == 0;
return super::readFileHeader(); return super::readFileHeader();
} }
@@ -173,14 +173,12 @@ int PackW32Pe::readFileHeader()
// import handling // import handling
**************************************************************************/ **************************************************************************/
struct import_desc __packed_struct(import_desc)
{
LE32 oft; // orig first thunk LE32 oft; // orig first thunk
char _[8]; char _[8];
LE32 dllname; LE32 dllname;
LE32 iat; // import address table LE32 iat; // import address table
} __packed_struct_end()
__attribute_packed;
void PackW32Pe::processImports(unsigned myimport, unsigned) // pass 2 void PackW32Pe::processImports(unsigned myimport, unsigned) // pass 2
{ {
@@ -1105,7 +1103,7 @@ void PackW32Pe::pack(OutputFile *fo)
int PackW32Pe::canUnpack() int PackW32Pe::canUnpack()
{ {
if (!readFileHeader()) if (!readFileHeader() || ih.cpu < 0x14c || ih.cpu > 0x150)
return false; return false;
unsigned objs = ih.objects; unsigned objs = ih.objects;
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -485,7 +485,7 @@ void PackWcle::pack(OutputFile *fo)
const unsigned text_vaddr = IOT(ih.init_cs_object-1,my_base_address); const unsigned text_vaddr = IOT(ih.init_cs_object-1,my_base_address);
// attach some useful data at the end of preprocessed fixups // attach some useful data at the end of preprocessed fixups
ifixups[sofixups++] = (unsigned char) ih.automatic_data_object; ifixups[sofixups++] = (unsigned char) (ih.automatic_data_object & 0xff);
unsigned ic = objects*sizeof(*iobject_table); unsigned ic = objects*sizeof(*iobject_table);
memcpy(ifixups+sofixups,iobject_desc,ic); memcpy(ifixups+sofixups,iobject_desc,ic);
iobject_desc.dealloc(); iobject_desc.dealloc();
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2008 Laszlo Molnar Copyright (C) 1996-2009 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them

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