1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

support for arm/WinCE ("arm/pe") exes

committer: ml1050 <ml1050> 1126255781 +0000
This commit is contained in:
László Molnár 2005-09-09 08:49:41 +00:00
parent 14d303d331
commit 572314bf3f
13 changed files with 2827 additions and 5 deletions

View File

@ -42,8 +42,6 @@ More formats:
- freebsd/386 (generic), freebsd/elf386 (specialized).
Probably could share most of the linux code.
- Windows CE
- add support for self-extracting HTML pages using a Javascript stub
(like the AlgART HTML Packer "AHP")

2
README
View File

@ -149,7 +149,7 @@ Markus & Laszlo
Markus F.X.J. Oberhumer Laszlo Molnar
markus@oberhumer.com ml1050@cdata.tvnet.hu
markus@oberhumer.com ml1050@users.sourceforge.net

View File

@ -30,4 +30,5 @@ The main news since 1.25 are:
shell-to-memory decompression ("linux/sh386")
- support for playstation exes ("ps1/exe")
- lots of new bugs ;-) take care
- support for arm/WinCE ("arm/pe") exes

View File

@ -454,6 +454,7 @@ inline void operator delete[](void *p)
#define UPX_F_PS1_EXE 18
#define UPX_F_VMLINUX_i386 19
#define UPX_F_LINUX_ELFI_i386 20
#define UPX_F_WINCE_ARM_PE 21
#define UPX_F_ATARI_TOS 129
#define UPX_F_SOLARIS_SPARC 130

2052
src/p_armpe.cpp Normal file

File diff suppressed because it is too large Load Diff

251
src/p_armpe.h Normal file
View File

@ -0,0 +1,251 @@
/* p_armpe.h --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2004 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
markus@oberhumer.com ml1050@users.sourceforge.net
*/
#ifndef __UPX_P_ARMPE_H
#define __UPX_P_ARMPE_H
class PackArmPe_Interval;
class PackArmPe_Reloc;
class PackArmPe_Resource;
class PackArmPe_Export;
/*************************************************************************
// w32/pe
**************************************************************************/
class PackArmPe : public Packer
{
typedef Packer super;
public:
PackArmPe(InputFile *f);
~PackArmPe();
virtual int getVersion() const { return 13; }
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
virtual const char *getName() const { return "arm/pe"; }
virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const;
virtual void pack(OutputFile *fo);
virtual void unpack(OutputFile *fo);
virtual bool canPack();
virtual int canUnpack();
// unpacker capabilities
virtual bool canUnpackVersion(int version) const
{ return false; }
protected:
virtual int readFileHeader();
virtual bool testUnpackVersion(int version) const;
virtual int buildLoader(const Filter *ft);
unsigned pe_offset;
unsigned processImports();
void processImports(unsigned);
void rebuildImports(upx_byte *&);
upx_byte *oimport;
unsigned soimport;
upx_byte *oimpdlls;
unsigned soimpdlls;
void processRelocs();
void processRelocs(PackArmPe_Reloc *);
void rebuildRelocs(upx_byte *&);
upx_byte *orelocs;
unsigned sorelocs;
upx_byte *oxrelocs;
unsigned soxrelocs;
void processExports(PackArmPe_Export *);
void processExports(PackArmPe_Export *,unsigned);
void rebuildExports();
upx_byte *oexport;
unsigned soexport;
void processResources(PackArmPe_Resource *);
void processResources(PackArmPe_Resource *, unsigned);
void rebuildResources(upx_byte *&);
upx_byte *oresources;
unsigned soresources;
void processTls(PackArmPe_Interval *);
void processTls(PackArmPe_Reloc *,const PackArmPe_Interval *,unsigned);
void rebuildTls();
upx_byte *otls;
unsigned sotls;
unsigned stripDebug(unsigned);
unsigned icondir_offset;
int icondir_count;
bool importbyordinal;
bool kernel32ordinal;
unsigned tlsindex;
unsigned rvamin;
unsigned cimports; // rva of preprocessed imports
unsigned crelocs; // rva of preprocessed fixups
int big_relocs;
struct pe_header_t
{
// 0x0
char _[4]; // pemagic
LE16 cpu;
LE16 objects;
char __[12]; // timestamp + reserved
LE16 opthdrsize;
LE16 flags;
// optional header
char ___[4]; // coffmagic + linkerversion
LE32 codesize;
// 0x20
LE32 datasize;
LE32 bsssize;
LE32 entry;
LE32 codebase;
// 0x30
LE32 database;
// nt specific fields
LE32 imagebase;
LE32 objectalign;
LE32 filealign; // should set to 0x200 ?
// 0x40
char ____[16]; // versions
// 0x50
LE32 imagesize;
LE32 headersize;
LE32 chksum; // should set to 0
LE16 subsystem;
LE16 dllflags;
// 0x60
char _____[20]; // stack + heap sizes
// 0x74
LE32 ddirsentries; // usually 16
struct ddirs_t
{
LE32 vaddr;
LE32 size;
}
__attribute_packed;
struct ddirs_t ddirs[16];
}
__attribute_packed;
struct pe_section_t
{
char name[8];
LE32 vsize;
LE32 vaddr;
LE32 size;
LE32 rawdataptr;
char _[12];
LE32 flags;
}
__attribute_packed;
pe_header_t ih, oh;
pe_section_t *isection;
static unsigned virta2objnum (unsigned, pe_section_t *, unsigned);
unsigned tryremove (unsigned, unsigned);
enum {
PEDIR_EXPORT = 0,
PEDIR_IMPORT = 1,
PEDIR_RESOURCE = 2,
PEDIR_EXCEPTION = 3, // Exception table
PEDIR_SEC = 4, // Certificate table (file pointer)
PEDIR_RELOC = 5,
PEDIR_DEBUG = 6,
PEDIR_COPYRIGHT = 7, // Architecture-specific data
PEDIR_GLOBALPTR = 8, // Global pointer
PEDIR_TLS = 9,
PEDIR_LOADCONF = 10, // Load Config Table
PEDIR_BOUNDIM = 11,
PEDIR_IAT = 12,
PEDIR_DELAYIMP = 13, // Delay Import Descriptor
PEDIR_COMRT = 14 // Com+ Runtime Header
};
enum {
PEFL_CODE = 0x20,
PEFL_DATA = 0x40,
PEFL_BSS = 0x80,
PEFL_INFO = 0x200,
PEFL_EXTRELS = 0x01000000, // extended relocations
PEFL_DISCARD = 0x02000000,
PEFL_NOCACHE = 0x04000000,
PEFL_NOPAGE = 0x08000000,
PEFL_SHARED = 0x10000000,
PEFL_EXEC = 0x20000000,
PEFL_READ = 0x40000000,
PEFL_WRITE = 0x80000000
};
enum {
RELOCS_STRIPPED = 0x0001,
EXECUTABLE = 0x0002,
LNUM_STRIPPED = 0x0004,
LSYMS_STRIPPED = 0x0008,
AGGRESSIVE_TRIM = 0x0010,
TWO_GIGS_AWARE = 0x0020,
FLITTLE_ENDIAN = 0x0080,
BITS_32_MACHINE = 0x0100,
DEBUG_STRIPPED = 0x0200,
REMOVABLE_SWAP = 0x0400,
SYSTEM_PROGRAM = 0x1000,
DLL_FLAG = 0x2000,
FBIG_ENDIAN = 0x8000
};
// predefined resource types
enum {
RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING,
RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE,
RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE,
RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML,
RT_MANIFEST, RT_LAST
};
};
#endif /* already included */
/*
vi:ts=4:et
*/

View File

@ -53,6 +53,7 @@
#include "p_vmlinx.h"
#include "p_ps1.h"
#include "p_mach.h"
#include "p_armpe.h"
/*************************************************************************
@ -170,6 +171,8 @@ static Packer* try_packers(InputFile *f, try_function func)
#endif
if ((p = func(new PackW16Ne(f),f)) != NULL)
return p;
if ((p = func(new PackArmPe(f),f)) != NULL)
return p;
if ((p = func(new PackW32Pe(f),f)) != NULL)
return p;
}

View File

@ -12,3 +12,5 @@ stamp-h
stubify.exe
upxb
upxd
*.out
*.ah

View File

@ -46,7 +46,8 @@ STUBS = \
l_lx_pti86.h fold_pti86.h \
l_lx_elfppc32.h fold_elfppc32.h \
l_mac_ppc32.h fold_machppc32.h \
l_vmlinz.h l_vmlinx.h
l_vmlinz.h l_vmlinx.h \
l_armpe.h
# experimental:
ifneq ($(strip $(wildcard $(srcdir)/l_ext2.asm)),)
@ -178,6 +179,15 @@ ifneq ($(wildcard $d),)
endif
###
### ARM-PE-WINCE
###
GCC_WINCE := arm-wince-pe-gcc -Os
LD_WINCE := arm-wince-pe-ld
OBJCOPY_WINCE := arm-wince-pe-objcopy
BIN2H_WINCE := perl -ne 'print "db\t", join(",", map { sprintf "%\#02x", $$_ } unpack("C*", $$_)), "\n"'
# /***********************************************************************
# // main targets
# ************************************************************************/
@ -276,7 +286,6 @@ l_w32pe.h: l_w32pe.asx
$(NASM) -f bin -o $T.bin $<
$(BIN2H) $T.bin nrv_loader $@
# /***********************************************************************
# // atari/tos rules
# ************************************************************************/
@ -477,6 +486,14 @@ upxd: l_lx_sep.o l_lx_sep86.asm
$(STRIPELF_LINUX_I386) $@
$(BRANDELF) $@
l_armpe.h: l_armpe.asx l_armpe_s.S l_armpe_c.c
$(GCC_WINCE) -c l_armpe_s.S l_armpe_c.c
$(LD_WINCE) -nostdlib -o l_armpe_.out l_armpe_s.o l_armpe_c.o
$(OBJCOPY_WINCE) --only-section .text -O binary l_armpe_.out l_armpe_.bin
$(BIN2H_WINCE) <l_armpe_.bin >l_armpe_.ah
$(NASM) -f bin -o $T.bin $<
$(BIN2H) $T.bin nrv_loader $@
# /***********************************************************************
# // dependencies
@ -506,6 +523,7 @@ l_vmlinx.h: $(DEPS2) $(DEPS3)
l_vxd.h: $(DEPS2) $(DEPS3)
l_wcle.h: $(DEPS2) $(DEPS3)
l_w32pe.h: $(DEPS2) $(DEPS3)
l_armpe.h: $(DEPS2) $(DEPS3)
l_lx_elf86.h: l_lx_elf86.asm macros.ash macros.asy $(DEPS3)
l_lx_exec86.h: l_lx_exec86.asm macros.ash macros.asy $(DEPS3)

53
src/stub/l_armpe.asm Normal file
View File

@ -0,0 +1,53 @@
; l_armwce.asm -- loader & decompressor for the arm/wince/pe format
;
; This file is part of the UPX executable compressor.
;
; Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
; Copyright (C) 1996-2004 Laszlo Molnar
; All Rights Reserved.
;
; UPX and the UCL library are free software; you can redistribute them
; and/or modify them under the terms of the GNU General Public License as
; published by the Free Software Foundation; either version 2 of
; the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; see the file COPYING.
; If not, write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;
; Markus F.X.J. Oberhumer Laszlo Molnar
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
;
%define jmps jmp short
%define jmpn jmp near
%include "macros.ash"
BITS 32
SECTION .text
ORG 0
CPU 386
; =============
; ============= ENTRY POINT
; =============
; __ARMWPE00__
start:
%include "l_armpe_.ah"
%include "header.ash"
eof:
; __ARMWPE99__
section .data
dd -1
dw eof
; vi:ts=8:et:nowrap

100
src/stub/l_armpe.h Normal file
View File

@ -0,0 +1,100 @@
/* l_armpe.h -- created from l_armpe.bin, 1069 (0x42d) bytes
This file is part of the UPX executable compressor.
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2005 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
*/
#define NRV_LOADER_ADLER32 0x793a99ed
#define NRV_LOADER_CRC32 0x90e7375f
unsigned char nrv_loader[1069] = {
15, 64, 45,233, 12, 0,160,227, 0, 0,143,224, 11, 0, 0,235, /* 0x 0 */
15, 64,189,232, 24,240,159,229, 88,120,120, 88, 83, 82, 67, 48, /* 0x 10 */
68, 83, 84, 48, 66, 73, 77, 80, 79, 78, 65, 77, 71, 69, 84, 80, /* 0x 20 */
76, 79, 65, 68, 69, 78, 84, 82, 83, 82, 67, 76, 68, 83, 84, 76, /* 0x 30 */
240, 71, 45,233, 4, 80,144,228, 0, 48,160,227, 4,112,144,228, /* 0x 40 */
136,208, 77,226, 4, 32,144,228, 4, 48,141,229, 4,144,144,228, /* 0x 50 */
3, 64,160,225, 4,128,144,228, 0, 32,141,229, 0, 96,144,229, /* 0x 60 */
3,192,160,225, 3, 0,160,225, 1,160,160,227, 4, 0, 0,234, /* 0x 70 */
5, 48,132,224, 0, 48,211,229, 1, 64,132,226, 7, 48,192,231, /* 0x 80 */
1, 0,128,226,127, 0, 28,227, 5, 48,212, 7,140, 48,160, 17, /* 0x 90 */
131, 48,160, 1, 1, 48,131, 2, 1, 64,132, 2, 1, 12, 19,227, /* 0x a0 */
3,192,160,225,241,255,255, 26, 1, 16,160,227,127, 0, 28,227, /* 0x b0 */
5, 48,212, 7,140, 48,160, 17,131, 48,160, 1, 1, 48,131, 2, /* 0x c0 */
1, 64,132, 2, 3,192,160,225,127, 0, 19,227,129, 32,160,225, /* 0x d0 */
131, 59,160,225,163, 31,130,225, 5, 48,212, 7,140, 48,160, 17, /* 0x e0 */
131, 48,160, 1, 1, 48,131, 2, 1, 64,132, 2, 1, 12, 19,227, /* 0x f0 */
3,192,160,225, 11, 0, 0, 26,127, 0, 19,227, 5, 48,212, 7, /* 0x 100 */
131, 48,160, 17,131, 48,160, 1, 1, 48,131, 2,129, 32,160,225, /* 0x 110 */
3,192,160,225,131, 59,160,225,163, 63,130,225, 1, 64,132, 2, /* 0x 120 */
2, 16, 67,226,224,255,255,234, 2, 0, 81,227, 10, 0, 0, 26, /* 0x 130 */
127, 0, 19,227, 5, 48,212, 7,131, 48,160, 17,131, 48,160, 1, /* 0x 140 */
1, 48,131, 2, 3,192,160,225, 35, 52,160,225, 10, 16,160,225, /* 0x 150 */
1, 64,132, 2, 1, 32, 3,226, 10, 0, 0,234, 5, 48,212,231, /* 0x 160 */
1, 64,132,226, 1, 52,131,224, 3, 28, 67,226, 1, 0,113,227, /* 0x 170 */
71, 0, 0, 10, 1, 48,224,225,161, 16,160,225, 1, 16,129,226, /* 0x 180 */
1, 32, 3,226, 1,160,160,225, 0, 0, 82,227,127, 48, 12,226, /* 0x 190 */
10, 0, 0, 10, 0, 0, 83,227, 5, 48,212, 7,140, 48,160, 17, /* 0x 1a0 */
131, 48,160, 1, 1, 48,131, 2, 3,192,160,225, 35, 52,160,225, /* 0x 1b0 */
1, 48, 3,226, 1, 64,132, 2, 1, 32,131,226, 39, 0, 0,234, /* 0x 1c0 */
0, 0, 83,227, 5, 48,212, 7,140, 48,160, 17,131, 48,160, 1, /* 0x 1d0 */
1, 48,131, 2, 1, 64,132, 2, 1, 12, 19,227, 3,192,160,225, /* 0x 1e0 */
1, 32,160, 3, 10, 0, 0, 10,127, 0, 19,227, 5, 48,212, 7, /* 0x 1f0 */
131, 48,160, 17,131, 48,160, 1, 1, 48,131, 2, 3,192,160,225, /* 0x 200 */
35, 52,160,225, 1, 48, 3,226, 1, 64,132, 2, 3, 32,131,226, /* 0x 210 */
18, 0, 0,234,127, 0, 28,227,140, 48,160,225, 5, 48,212, 7, /* 0x 220 */
130, 32,160,225,131, 48,160, 1, 1, 48,131, 2,131,224,160,225, /* 0x 230 */
1, 64,132, 2,127, 0, 19,227,131, 59,160,225,163, 47,130,225, /* 0x 240 */
5, 48,212, 7, 1, 64,132, 2,131, 48,160, 1, 1,224,131, 2, /* 0x 250 */
1, 12, 30,227, 14,192,160,225,237,255,255, 10, 3, 32,130,226, /* 0x 260 */
0, 48,135,224, 3,224, 97,224, 1, 48,222,228, 5, 12, 81,227, /* 0x 270 */
1, 32,130,130, 0, 48,199,231, 1, 0,128,226, 1, 48,222,228, /* 0x 280 */
1, 32, 82,226, 7, 48,192,231, 1, 0,128,226,250,255,255, 26, /* 0x 290 */
123,255,255,234, 0,160,150,229, 0,128,152,229, 0, 64,157,229, /* 0x 2a0 */
4, 0,141,229, 3, 16,212,229, 2, 48,212,229, 1, 32,212,229, /* 0x 2b0 */
1, 52,131,224, 0, 16,212,229, 3, 36,130,224, 2,228,129,224, /* 0x 2c0 */
0, 0, 94,227, 59, 0, 0, 10, 4, 48,132,226, 3, 16,211,229, /* 0x 2d0 */
2, 32,211,229, 1, 48,211,229, 1, 36,130,224, 4, 16,212,229, /* 0x 2e0 */
2, 52,131,224, 9,192,254,231, 3, 20,129,224, 8, 0,141,226, /* 0x 2f0 */
0, 0, 92,227, 7, 80,129,224, 0, 48,160,225, 3, 0, 0, 10, /* 0x 300 */
178,192,195,224, 1,192,254,229, 0, 0, 92,227,250,255,255,234, /* 0x 310 */
0, 32,160,227,176, 32,195,225, 15,224,160,225, 10,240,160,225, /* 0x 320 */
8, 48,244,229, 0, 96,160,225, 0, 0, 83,227, 31, 0, 0, 10, /* 0x 330 */
255, 48, 3,226, 1, 0, 83,227, 1, 64,132,226, 2, 0, 0, 10, /* 0x 340 */
255, 0, 83,227, 9, 0, 0, 10, 19, 0, 0,234, 6, 0,160,225, /* 0x 350 */
4, 16,160,225, 15,224,160,225, 8,240,160,225, 4, 0,133,228, /* 0x 360 */
1, 48,212,228, 0, 0, 83,227,252,255,255, 26, 13, 0, 0,234, /* 0x 370 */
0, 48,212,229, 1, 16,212,229, 6, 0,160,225, 1, 20,131,224, /* 0x 380 */
15,224,160,225, 8,240,160,225, 2, 64,132,226, 5, 48,160,225, /* 0x 390 */
4, 80,133,226, 0, 0,131,229, 2, 0, 0,234, 0, 32,160,227, /* 0x 3a0 */
1, 48,160,227, 0, 32,131,229, 0, 48,212,229,221,255,255,234, /* 0x 3b0 */
1, 64,132,226,186,255,255,234,136,208,141,226,240,135,189,232, /* 0x 3c0 */
255,255,255,255, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, /* 0x 3d0 */
85, 80, 88, 33,161,216,208,213, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 3e0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, /* 0x 3f0 */
65, 82, 77, 87, 80, 69, 48, 48, 0, 0, 0, 0, 0, 85, 80, 88, /* 0x 400 */
49, 72, 69, 65, 68, 0,224, 3, 0, 0, 65, 82, 77, 87, 80, 69, /* 0x 410 */
57, 57, 0, 0, 4, 0, 0,255,255,255,255, 0, 4 /* 0x 420 */
};

326
src/stub/l_armpe_c.c Normal file
View File

@ -0,0 +1,326 @@
#define WRITEFILE(name0, buf, len) \
do { short b[3]; b[0] = '\\'; b[1] = name0; b[2] = 0; \
typedef int (*CF)(short *, int, int, int, int, int, int); CF cf = (CF) 0x1f99c58; \
typedef void (*WF)(int, const void *, int, int *, int); WF wf = (WF) 0x1f99d60; \
typedef void (*CH)(int); CH ch = (CH) 0x1f9a2f0; \
int h = cf(b, 0x40000000L, 3, 0, 2, 0x80, 0);\
int l; wf(h, buf, len, &l, 0); \
ch(h); } while (0)
typedef unsigned int ucl_uint32;
typedef int ucl_int32;
typedef unsigned int ucl_uint;
typedef int ucl_int;
static int
ucl_nrv2e_decompress_8 ( const unsigned char * src, ucl_uint src_len,
unsigned char * dst, ucl_uint * dst_len)
{
{
ucl_uint32 bb = 0;
ucl_uint ilen = 0, olen = 0, last_m_off = 1;
for (;;)
{
ucl_uint m_off, m_len;
while ((((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1))
{
;
;
dst[olen++] = src[ilen++];
}
m_off = 1;
for (;;)
{
m_off = m_off*2 + (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1);
;
;
if ((((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)) break;
m_off = (m_off-1)*2 + (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1);
}
if (m_off == 2)
{
m_off = last_m_off;
m_len = (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1);
}
else
{
;
m_off = (m_off-3)*256 + src[ilen++];
if (m_off == ((0xffffffff) + 0U))
break;
m_len = (m_off ^ ((0xffffffff) + 0U)) & 1;
m_off >>= 1;
last_m_off = ++m_off;
}
if (m_len)
m_len = 1 + (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1);
else if ((((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1))
m_len = 3 + (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1);
else
{
m_len++;
do {
m_len = m_len*2 + (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1);
;
;
} while (!(((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1));
m_len += 3;
}
m_len += (m_off > 0x500);
;
;
{
const unsigned char * m_pos;
m_pos = dst + olen - m_off;
dst[olen++] = *m_pos++;
do dst[olen++] = *m_pos++; while (--m_len > 0);
}
}
*dst_len = olen;
return ilen == src_len ? 0 : (ilen < src_len ? (-205) : (-201));
}
}
typedef void *(*loadlibraryw)(unsigned short *);
typedef void *(*getprocaddra)(void *, void *);
#define T(a,b,c,d) ((a) + ((b) * 0x100) + ((c) * 0x10000) + ((d) * 0x1000000))
static inline void *get_le32(unsigned char *p)
{
return (void*) T(p[0], p[1], p[2], p[3]);
}
static void handle_imports(unsigned char *imp,
unsigned name_offset,
unsigned iat_offset,
loadlibraryw ll,
getprocaddra gpa)
{
unsigned short buf[64];
while (1)
{
unsigned short *b;
//printf("name=%p iat=%p\n", get_le32(imp), get_le32(imp + 4));
unsigned char *name = get_le32(imp);
if (name == 0)
break;
name += name_offset;
unsigned *iat = get_le32(imp + 4) + iat_offset;
//printf("name=%p iat=%p\n", name, iat);
for (b = buf; *name; name++, b++)
*b = *name;
*b = 0;
void *dll = ll(buf);
imp += 8;
unsigned ord;
while (*imp)
{
switch (*imp++)
{
case 1:
// by name
*iat++ = (unsigned) gpa(dll, imp);
while (*imp++)
;
break;
case 0xff:
// by ordinal
ord = ((unsigned) imp[0]) + imp[1] * 0x100;
imp += 2;
*iat++ = (unsigned) gpa(dll, (void *) ord);
break;
default:
*(int*) 1 = 0;
break;
}
}
imp++;
}
}
void upx_main(unsigned *info)
{
int dlen = 0;
unsigned src0 = *info++;
unsigned dst0 = *info++;
unsigned bimp = *info++;
unsigned onam = *info++;
unsigned getp = *info++;
unsigned load = *info++;
unsigned entr = *info++;
unsigned srcl = *info++;
unsigned dstl = *info++;
//WRITEFILE('1', (void*) 0x11000, load + 256 - 0x11000);
ucl_nrv2e_decompress_8((void *) src0, srcl, (void *) dst0, &dlen);
handle_imports((void *) bimp, onam, dst0, *(void**) load, *(void**) getp);
//WRITEFILE('2', (void*) 0x11000, load + 256 - 0x11000);
}
#ifndef __pe__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void *test_loadlibraryw(unsigned short *x)
{
printf("loadlibraryw called: ");
while (*x)
printf("%c", *x++);
printf("\n");
static unsigned ret = 0x2a2a2a00;
return (void*) ret++;
}
static void *test_getprocaddra(void *a, void *x)
{
if ((unsigned) x < 0x10000)
printf("getprocaddra called: %p %x\n", a, (unsigned) x);
else
printf("getprocaddra called: %p %s\n", a, (char*) x);
static unsigned ret = 1;
return a + ret++;
}
int main(int argc, char **argv)
{
if (argc != 2)
return printf("usage: %s <compressed.exe>\n", argv[0]);
void *mem = malloc(32*1024*1024);
void *mem16m = (void*) ((((unsigned) mem) + 0xffffff) & 0xff000000);
printf("mem: %p %p\n", mem, mem16m);
char command[100 + strlen(argv[1])];
snprintf(command, sizeof(command),
"arm-wince-pe-objdump -h '%s'|grep '2[*][*]2'", argv[1]);
FILE *fp = popen(command, "r");
if (fgets(command, 100, fp) == NULL)
return printf("error while calling objdump\n");
unsigned start_uncompressed;
if (sscanf(command, "%*d %*s %*x %x", &start_uncompressed) != 1)
return printf("scanf failed on '%s'", command);
printf("start_uncompressed=%x ", start_uncompressed);
if (fgets(command, 100, fp) == NULL)
return printf("error while calling objdump\n");
unsigned size;
unsigned offset;
unsigned vma;
if (sscanf(command, "%*d %*s %x %x %*x %x", &size, &vma, &offset) != 3)
return printf("scanf failed on '%s'" , command);
printf("size=%x vma=%x offset=%x\n", size, vma, offset);
if (fgets(command, 100, fp) == NULL)
return printf("error while calling objdump\n");
unsigned size2;
unsigned offset2;
unsigned vma2;
if (sscanf(command, "%*d %*s %x %x %*x %x", &size2, &vma2, &offset2) != 3)
return printf("scanf failed on '%s'" , command);
printf("size2=%x vma2=%x offset2=%x\n", size2, vma2, offset2);
pclose(fp);
FILE *f1 = fopen(argv[1], "rb");
if (f1 == NULL)
return printf("can not open %s\n", argv[1]);
if (fseek(f1, offset, SEEK_SET))
return printf("fseek failed\n");
if (fread(mem16m + vma, size, 1, f1) != 1)
return printf("fread failed\n");
if (fseek(f1, offset2, SEEK_SET))
return printf("fseek failed\n");
if (fread(mem16m + vma2, size2, 1, f1) != 1)
return printf("fread failed\n");
fclose(f1);
unsigned *info = (unsigned *) memmem(mem16m + vma, size, "XxxX", 4);
if (info == NULL)
return printf("decompression info not found\n");
info++;
unsigned src0 = *info++;
unsigned dst0 = *info++;
unsigned bimp = *info++;
unsigned onam = *info++;
unsigned getp = *info++;
unsigned load = *info++;
unsigned entr = *info++;
unsigned srcl = *info++;
unsigned dstl = *info++;
printf("%x %x %x %x %x %x %x %x %x\n", src0, srcl, dst0, dstl, bimp, onam, load, getp, entr);
int dlen = 0;
int ret = ucl_nrv2e_decompress_8(mem16m + src0, srcl, mem16m + dst0, &dlen);
printf("dlen=%x, ret=%d\n", dlen, ret);
if (dlen != (int) dstl)
return printf("corrupt compressed data\n");
f1 = fopen("/tmp/image.out", "w");
fwrite(mem16m, vma + size + 0x10000, 1, f1);
fclose(f1);
handle_imports(bimp + mem16m, onam + mem16m, dst0 + mem16m,
test_loadlibraryw, test_getprocaddra);
f1 = fopen("/tmp/image.out", "w");
fwrite(mem16m, vma2 + size2, 1, f1);
fclose(f1);
return 0;
}
#endif
#if 0
int main(void)
{
FILE *f1 = fopen("/r", "w");
int h = LoadLibraryW(L"coredll.dll");
fprintf(f1, "%p\n", GetProcAddressA(h, "DeleteFileW"));
fclose(f1);
return 0;
}
int main(void)
{
typedef void (*df)(ushort *);
df dfw = 0x1f99bc8;
dfw(L"\\r");
return 0;
}
#endif

17
src/stub/l_armpe_s.S Normal file
View File

@ -0,0 +1,17 @@
.text
.align 0
.global _mainCRTStartup
_mainCRTStartup:
stmfd sp!, {r0 - r3, lr}
mov r0, #L2 - L0 - 8
L0:
add r0, pc, r0
bl _upx_main
ldmfd sp!, {r0 - r3, lr}
ldr pc, L21
.ascii "XxxX"
L2:
.ascii "SRC0DST0BIMPONAMGETPLOAD"
L21:
.ascii "ENTRSRCLDSTL"