arm/pe: the assembly thumb mode decompressor is used in the stub

arm/pe: the C part of the stub is compiled as thumb

committer: ml1050 <ml1050> 1143449862 +0000
This commit is contained in:
László Molnár 2006-03-27 08:57:42 +00:00
parent a7bff34784
commit 984ec25132
6 changed files with 198 additions and 361 deletions

View File

@ -1794,15 +1794,14 @@ void PackArmPe::pack(OutputFile *fo)
const unsigned myimport = ncsection + soresources - rvamin;
// patch loader
patch_le32(loader, codesize, "DSTL", ph.u_len);
patch_le32(loader, codesize, "SRCL", ph.c_len);
patch_le32(loader, codesize, "ENTR", ih.entry + ih.imagebase);
patch_le32(loader, codesize, "LOAD", ih.imagebase + rvamin + myimport + get_le32(oimpdlls + 16));
patch_le32(loader, codesize, "GETP", ih.imagebase + rvamin + myimport + get_le32(oimpdlls + 16) + 4);
patch_le32(loader, codesize, "ONAM", ih.imagebase + myimport + rvamin);
patch_le32(loader, codesize, "BIMP", ih.imagebase + rvamin + cimports);
patch_le32(loader, codesize, "DSTL", ph.u_len);
patch_le32(loader, codesize, "DST0", ih.imagebase + rvamin);
patch_le32(loader, codesize, "SRCL", ph.c_len);
patch_le32(loader, codesize, "SRC0", ih.imagebase + s1addr + ic);
#if 0
if (ih.entry)

View File

@ -222,9 +222,9 @@ endif
### ARM-PE-WINCE
###
GCC_WINCE := arm-wince-pe-gcc -Os
LD_WINCE := arm-wince-pe-ld
OBJCOPY_WINCE := arm-wince-pe-objcopy
GCC_ARM := arm-9tdmi-linux-gnu-gcc -Os -march=armv5t
LD_ARM := arm-9tdmi-linux-gnu-ld
OBJCOPY_ARM := arm-9tdmi-linux-gnu-objcopy
BIN2H_WINCE := perl -ne 'print "db\t", join(",", map { sprintf "%\#02x", $$_ } unpack("C*", $$_)), "\n"'
@ -551,10 +551,11 @@ 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
l_armpe.h: l_armpe.asx l_armpe_s.S l_armpe_c.c arm_nrv2e_d8.S
$(GCC_ARM) -c -mthumb-interwork l_armpe_s.S arm_nrv2e_d8.S
$(GCC_ARM) -c -mthumb -mthumb-interwork l_armpe_c.c
$(LD_ARM) -o l_armpe_.out l_armpe_s.o l_armpe_c.o arm_nrv2e_d8.o
$(OBJCOPY_ARM) --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 $@

View File

@ -77,6 +77,8 @@ ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 @ ARM mode
*/
adr r12,1+thumb_nrv2e_d8; bx r12 @ enter THUMB mode
.code 16 @ THUMB mode
.globl thumb_nrv2e_d8
.thumb_func
thumb_nrv2e_d8:
push {r2,r3, r4,r5,r6,r7, lr}
#define sp_DST0 0 /* stack offset of original dst */

View File

@ -1,9 +1,10 @@
/* l_armpe.h -- created from l_armpe.bin, 1069 (0x42d) bytes
/* l_armpe.h -- created from l_armpe.bin, 569 (0x239) 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
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2006 Laszlo Molnar
Copyright (C) 2000-2006 John F. Reiser
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
@ -26,75 +27,45 @@
*/
#define NRV_LOADER_ADLER32 0x793a99ed
#define NRV_LOADER_CRC32 0x90e7375f
#define NRV_LOADER_SIZE 569
#define NRV_LOADER_ADLER32 0xf95bc91d
#define NRV_LOADER_CRC32 0x9d6cf681
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 */
unsigned char nrv_loader[569] = {
15, 64, 45,233, 48, 0,143,226, 14, 0,144,232, 2, 16,129,224, /* 0x 0 */
0, 32,147,229, 1, 58,131,226, 1, 0, 83,225,251,255,255,154, /* 0x 10 */
20, 0, 0,250, 15, 64,189,232, 44,240,159,229, 9, 75, 27,104, /* 0x 20 */
24, 71, 9, 75,251,231, 0, 0, 88,120,120, 88, 83, 82, 67, 48, /* 0x 30 */
83, 82, 67, 76, 68, 83, 84, 48, 68, 83, 84, 76, 66, 73, 77, 80, /* 0x 40 */
79, 78, 65, 77, 71, 69, 84, 80, 76, 79, 65, 68, 69, 78, 84, 82, /* 0x 50 */
2, 28,192,120,147,120, 0, 2,192, 24, 83,120, 0, 2,192, 24, /* 0x 60 */
19,120, 0, 2,192, 24,112, 71,240,181,163,176, 0, 35, 2,147, /* 0x 70 */
8,200, 2,200, 4,200, 4, 48, 16,200, 0,104, 0,144, 24, 28, /* 0x 80 */
2,171, 1,146, 0,240, 80,248, 37, 28, 40, 28,255,247,224,255, /* 0x 90 */
4, 30, 65,208, 0,155, 40, 29,228, 24,255,247,217,255, 1,154, /* 0x a0 */
134, 24, 3,168, 2, 28, 35,120, 27, 6, 0, 43, 4,208, 27, 14, /* 0x b0 */
19,128, 1, 52, 2, 50,246,231, 0, 35, 19,128,255,247,177,255, /* 0x c0 */
8, 53, 7, 28, 43,120, 27, 6, 0, 43, 35,208, 27, 14, 1, 53, /* 0x d0 */
1, 43, 2,208,255, 43, 13,208, 24,224, 56, 28, 41, 28,255,247, /* 0x e0 */
157,255, 52, 28, 32, 96, 4, 54, 43,120, 27, 6, 1, 53, 0, 43, /* 0x f0 */
250,209,231,231,105,120, 43,120, 9, 2, 56, 28, 89, 24,255,247, /* 0x 100 */
141,255, 52, 28, 2, 53, 4, 54, 32, 96,219,231, 0, 34, 1, 35, /* 0x 110 */
26, 96,215,231, 1, 53,184,231, 35,176,240,188, 1,188, 0, 71, /* 0x 120 */
1,192,143,226, 28,255, 47,225,252,181, 15, 24, 1, 36,101, 66, /* 0x 130 */
228, 7, 5, 38, 54, 2, 15,224, 24,188,192, 27,210, 26, 34, 96, /* 0x 140 */
240,188, 2,188, 8, 71, 4,120,100, 65, 1, 48, 36, 6,247, 70, /* 0x 150 */
3,120, 1, 48, 19,112, 1, 50, 36, 25,254, 70,243,208,247,210, /* 0x 160 */
1, 33, 4,224, 1, 57, 36, 25,254, 70,236,208, 73, 65, 36, 25, /* 0x 170 */
254, 70,232,208, 73, 65, 36, 25,254, 70,228,208,242,211,203, 30, /* 0x 180 */
0, 33, 8,211, 27, 2, 5,120, 1, 48, 29, 67,237, 67,211,208, /* 0x 190 */
109, 16, 19,210, 3,224, 36, 25,254, 70,212,208, 14,210, 1, 33, /* 0x 1a0 */
36, 25,254, 70,207,208, 9,210, 36, 25,254, 70,203,208, 73, 65, /* 0x 1b0 */
36, 25,254, 70,199,208,247,211, 4, 49, 4,224, 36, 25,254, 70, /* 0x 1c0 */
193,208, 73, 65, 2, 49,238, 66, 0,210, 1, 49, 19,120, 83, 93, /* 0x 1d0 */
19,112, 1, 50, 1, 57,250,209,190,231, 0, 0, 85, 80, 88, 33, /* 0x 1e0 */
161,216,208,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 1f0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 65, 82, 77, 87, /* 0x 200 */
80, 69, 48, 48, 0, 0, 0, 0, 0, 85, 80, 88, 49, 72, 69, 65, /* 0x 210 */
68, 0,236, 1, 0, 0, 65, 82, 77, 87, 80, 69, 57, 57, 0, 12, /* 0x 220 */
2, 0, 0,255,255,255,255, 12, 2 /* 0x 230 */
};

View File

@ -29,127 +29,20 @@
<jreiser@users.sourceforge.net>
*/
#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)
int thumb_nrv2e_d8(const unsigned char * src, unsigned src_len,
unsigned char * dst, unsigned * dst_len);
#define ucl_nrv2e_decompress_8 thumb_nrv2e_d8
void *LoadLibraryW(const unsigned short *);
void *GetProcAddressA(const void *, const void *);
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)
static void *get_le32(const unsigned char *p)
{
{
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));
}
return (void *) (p[0] + p[1] * 0x100 + p[2] * 0x10000 + p[3] * 0x1000000);
}
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)
static void handle_imports(const unsigned char *imp, unsigned name_offset,
unsigned iat_offset)
{
unsigned short buf[64];
while (1)
@ -166,7 +59,7 @@ static void handle_imports(unsigned char *imp,
*b = *name;
*b = 0;
void *dll = ll(buf);
void *dll = LoadLibraryW(buf);
imp += 8;
unsigned ord;
@ -176,7 +69,7 @@ static void handle_imports(unsigned char *imp,
{
case 1:
// by name
*iat++ = (unsigned) gpa(dll, imp);
*iat++ = (unsigned) GetProcAddressA(dll, imp);
while (*imp++)
;
break;
@ -184,7 +77,7 @@ static void handle_imports(unsigned char *imp,
// by ordinal
ord = ((unsigned) imp[0]) + imp[1] * 0x100;
imp += 2;
*iat++ = (unsigned) gpa(dll, (void *) ord);
*iat++ = (unsigned) GetProcAddressA(dll, (void *) ord);
break;
default:
*(int*) 1 = 0;
@ -195,163 +88,34 @@ static void handle_imports(unsigned char *imp,
}
}
void upx_main(unsigned *info)
// debugging stuff
int CFWrap(short *, int, int, int, int, int, int);
void WFwrap(int, const void *, int, int *, int);
void CHWrap(int);
#define WRITEFILE2(name0, buf, len) \
do { short b[3]; b[0] = '\\'; b[1] = name0; b[2] = 0; \
int h = CFwrap(b, 0x40000000L, 3, 0, 2, 0x80, 0);\
int l; WFwrap(h, buf, len, &l, 0); \
CHwrap(h); \
} while (0)
void upx_main(const unsigned *info)
{
int dlen = 0;
unsigned src0 = *info++;
unsigned srcl = *info++;
unsigned dst0 = *info++;
unsigned dstl = *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);
//WRITEFILE2('0', (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);
//WRITEFILE2('1', (void*) 0x11000, load + 256 - 0x11000);
handle_imports((void *) bimp, onam, dst0);
//WRITEFILE2('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

View File

@ -31,18 +31,118 @@
.text
.align 0
.global _mainCRTStartup
.globl upx_main
.globl _start
_mainCRTStartup:
_start:
stmfd sp!, {r0 - r3, lr}
mov r0, #L2 - L0 - 8
L0:
add r0, pc, r0
bl _upx_main
@ touch all pages in ARM mode - this seems to be required
@ otherwise the THUMB mode stuff fails
adr r0, SRC0
ldmia r0, {r1, r2, r3} @ r1 - src, r2 - slen, r3 - dst
add r1, r1, r2
L01:
ldr r2, [r3]
add r3, r3, #4096
cmp r3, r1
bls L01
blx upx_main @ call thumb
ldmfd sp!, {r0 - r3, lr}
ldr pc, L21
ldr pc, ENTR @ original entry
@@@@@@@@@@@@@@@@
.code 16
.global GetProcAddressA
.thumb_func
GetProcAddressA:
ldr r3, GETP
t_callr3:
ldr r3, [r3]
bx r3
@@@@@@@@@@@@@@@@
.global LoadLibraryW
.thumb_func
LoadLibraryW:
ldr r3, LLIB
b t_callr3
@@@@@@@@@@@@@@@@
#if 0
// debugging stuff - helpers for dumping memory to a file or deleting a file
// !!!!! check the lines with "system dependent" below before trying
.global CFwrap
.thumb_func
CFwrap:
push {r3}
ldr r3, createfilew
mov ip, r3
pop {r3}
bx ip
.global WFwrap
.thumb_func
WFwrap:
push {r3}
ldr r3, writefile
mov ip, r3
pop {r3}
bx ip
.global CHwrap
.thumb_func
CHwrap:
push {r3}
ldr r3, closehandle
mov ip, r3
pop {r3}
bx ip
.global DelFile
.thumb_func
DelFile:
adr r1, filename
strb r0, [r1, #2]
mov r0, r1
ldr r3, deleteffilew
mov ip, r3
bx ip
.code 32
createfilew:
.word 0x1f7927c @ system dependent
closehandle:
.word 0x1f71594 @ system dependent
deleteffilew:
.word 0x1f7b920 @ system dependent
writefile:
.word 0x1f79434 @ system dependent
filename:
.byte '\\', 0, 'r', 0, 0, 0
#endif
@@@@@@@@@@@@@@@@ paramater area for UPX
.code 32
.align 2
.ascii "XxxX"
L2:
.ascii "SRC0DST0BIMPONAMGETPLOAD"
L21:
.ascii "ENTRSRCLDSTL"
SRC0: .ascii "SRC0"
SRCL: .ascii "SRCL"
DST0: .ascii "DST0"
.ascii "DSTL"
.ascii "BIMPONAM"
GETP: .ascii "GETP"
LLIB: .ascii "LOAD"
ENTR: .ascii "ENTR"