From 984ec25132bd6a3bf7f0ec99d8a1ac2262e5f84b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Moln=C3=A1r?= Date: Mon, 27 Mar 2006 08:57:42 +0000 Subject: [PATCH] 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 1143449862 +0000 --- src/p_armpe.cpp | 5 +- src/stub/Makefile | 15 +- src/stub/arm_nrv2e_d8.S | 2 + src/stub/l_armpe.h | 117 ++++++---------- src/stub/l_armpe_c.c | 298 +++++----------------------------------- src/stub/l_armpe_s.S | 122 ++++++++++++++-- 6 files changed, 198 insertions(+), 361 deletions(-) diff --git a/src/p_armpe.cpp b/src/p_armpe.cpp index a621c6a1..4175ebc3 100644 --- a/src/p_armpe.cpp +++ b/src/p_armpe.cpp @@ -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) diff --git a/src/stub/Makefile b/src/stub/Makefile index 1bb14dec..0beb791b 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -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_.ah $(NASM) -f bin -o $T.bin $< $(BIN2H) $T.bin nrv_loader $@ diff --git a/src/stub/arm_nrv2e_d8.S b/src/stub/arm_nrv2e_d8.S index f9dcff43..b111d70f 100644 --- a/src/stub/arm_nrv2e_d8.S +++ b/src/stub/arm_nrv2e_d8.S @@ -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 */ diff --git a/src/stub/l_armpe.h b/src/stub/l_armpe.h index 837a6b09..1974dd56 100644 --- a/src/stub/l_armpe.h +++ b/src/stub/l_armpe.h @@ -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 */ }; diff --git a/src/stub/l_armpe_c.c b/src/stub/l_armpe_c.c index 14f53c8f..96457f40 100644 --- a/src/stub/l_armpe_c.c +++ b/src/stub/l_armpe_c.c @@ -29,127 +29,20 @@ */ -#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 -#include -#include - -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 \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 diff --git a/src/stub/l_armpe_s.S b/src/stub/l_armpe_s.S index efce714d..50c90958 100644 --- a/src/stub/l_armpe_s.S +++ b/src/stub/l_armpe_s.S @@ -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"