/* arm.v4t-wince.pe.S -- ARM/PE decompressor assembly startup (thumb mode) This file is part of the UPX executable compressor. Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2020 Laszlo Molnar Copyright (C) 2000-2020 John F. Reiser All Rights Reserved. UPX and the UCL library are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser */ #include "arch/arm/v4t/macros.S" // p_armpe.cpp uses some symbols, so they should be global .globl SRC0 .globl DST0 .globl IATT .globl ENTR .arm dst0 .req r8 @ global register section DllStart cmp r1, #1 bne .Lstart_orig section ExeStart stmfd sp!, {r0 - r11, lr} @ access all pages in ARM mode - this seems to be required @ otherwise the THUMB mode stuff fails adr r3, SRC0 ldmia r3, {r5, r6, r7, r8, r9, r10, r11} @ r7=dst0 add r5, pc, #4096 @ r3=addr src0, r11=LoadLibraryW .L01: @ r10=GetProcAddressA, r9=CacheSync ldr r6, [r7] add r7, r7, #4096 cmp r7, r5 bls .L01 adr r4, ProcessAll + 1 mov lr, pc bx r4 ldmfd sp!, {r0 - r11, lr} .Lstart_orig: ldr ip, ENTR bx ip SRC0: .long start_of_compressed SRCL: .long compressed_length DST0: .long start_of_uncompressed DSTL: .long uncompressed_length IATT: .long 0, 0, 0, 0 ENTR: .long original_entry .thumb ProcessAll: ldmia r3!, {r0, r1, r2} @ r0=src0, r1=slen, r2=dst0, r3=addr dstl mov dst0, r2 mov r4, r9 @ CacheSync push {r4, lr} @@ uncompress/unfilter/imports/relocs are copied here by the upx linker @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ section Unfilter_0x50 buffer .req r0 addval .req r2 bufend .req r4 ldr buffer, .LFIBS mov addval, #0 ldr bufend, .LFIBE mov r5, #0x0f mov r6, #0xff lsl r6, #24 mvn r7, r6 .Luf50_0: cmp buffer, bufend beq .Luf50_ret ldr r3, [buffer] lsr r1, r3, #24 and r1, r5 cmp r1, #0x0b bne .Luf50_1 mov r1, r3 and r1, r6 sub r3, addval and r3, r7 orr r3, r1 str r3, [buffer] .Luf50_1: add buffer, #4 add addval, #1 b .Luf50_0 .unreq buffer .unreq addval .unreq bufend .align 2 S(FIBS):.long filter_buffer_start S(FIBE):.long filter_buffer_end .Luf50_ret: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ section Relocs buffer .req r0 dest .req r1 addval .req r2 ldr buffer, .LBREL mov addval, dst0 sub dest, addval, #4 .Lreloc_loop: ldrb r3, [buffer] add buffer, #1 cmp r3, #0 beq .Lreloc_end cmp r3, #0xf0 blo .Lreloc_add mov r4, #0x0f and r4, r3 ldrb r3, [buffer, #1] @ get_le16 lsl r4, #8 add r4, r3 ldrb r3, [buffer] add buffer, #2 lsl r4, #8 add r3, r4 .Lreloc_add: add dest, r3 mov r5, #0 .Lread_be32: ldrb r3, [dest, r5] lsl r4, #8 add r4, r3 add r5, #1 cmp r5, #4 bne .Lread_be32 add r4, addval str r4, [dest] b .Lreloc_loop .align 2 S(BREL):.long start_of_relocs .Lreloc_end: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ section Imports imp .req r4 iat .req r5 dll .req r6 .real_start_ofImports: // suppress silly warnings mov r7, sp sub sp, #508 sub sp, #508 sub sp, #508 sub sp, #508 ldr imp, .LBIMP .Lhi_loop1: mov r0, imp bl get_le32 beq .Lhi_end ldr r1, .LONAM add r0, r1 mov r1, sp .Lhi_copyname: ldrb r2, [r0] add r0, #1 strh r2, [r1] add r1, #2 cmp r2, #0 bne .Lhi_copyname mov r0, sp bl LoadLibraryW mov dll, r0 add r0, imp, #4 bl get_le32 mov iat, dst0 add iat, r0 add imp, #8 .Lhi_gpa_loop: ldrb r0, [imp] add imp, #1 cmp r0, #1 bmi .Lhi_loop1 bne .Lhi_by_ord mov r1, imp .Lhi_by_name: ldrb r0, [imp] add imp, #1 cmp r0, #0 bne .Lhi_by_name b .Lhi_call_gpa .Lhi_by_ord: ldrb r0, [imp] ldrb r1, [imp, #1] add imp, #2 lsl r1, #8 add r1, r0 .Lhi_call_gpa: mov r0, dll bl GetProcAddressA stmia iat!, {r0} b .Lhi_gpa_loop .unreq iat .unreq imp .unreq dll get_le32: @ optimized for size mov r1, #3 .Lg0: ldrb r3, [r0, r1] lsl r2, r2, #8 add r2, r2, r3 sub r1, #1 bpl .Lg0 mov r0, r2 @ sets the Z flag if zero bx lr LoadLibraryW: bx r11 GetProcAddressA: bx r10 S(BIMP):.long start_of_imports S(ONAM):.long start_of_dll_names .Lhi_end: mov sp, r7 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ section ProcessEnd pop {r1, r2} @ r1=CacheSync, r2=lr mov r0, #4 @ parameter of CacheSync mov lr, r2 bx r1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "include/header.S" #define PURE_THUMB 1 section .ucl_nrv2b_decompress_8 #include "arch/arm/v4t/nrv2b_d8.S" #undef GETBIT #undef wrnk section Call2B bl .thumb_nrv2b_d8 section .ucl_nrv2e_decompress_8 #include "arch/arm/v4t/nrv2e_d8.S" #undef GETBIT #undef wrnk section Call2E bl .thumb_nrv2e_d8 #if 0 section .ucl_nrv2b_decompress_32 #include "arch/arm/v4t/nrv2b_d32.S" #undef GETBIT #undef wrnk #endif #if 0 section .ucl_nrv2e_decompress_32 #include "arch/arm/v4t/nrv2e_d32.S" #undef GETBIT #undef wrnk #endif //////////////////////////////////////// section CallLZMA // r0=src0, r1=slen, r2=dst0, r3=addr dstl parb .req r3 para .req r4 parc .req r5 pard .req r6 adr r7, .LzmaParams ldmia r7!, {parb, para, parc, pard} // load params mov r7, sp // save stack add para, sp mov r1, #0 .Lclearstack: push {r1} cmp sp, para bne .Lclearstack push {r2, parb, para} // out, outSize, &outSizeProcessed add r3, para, #4 // &inSizeProcessed mov r2, parc // inSize add r1, r0, #2 // in add r0, r3, #4 // &CLzmaDecoderState str pard, [r0] // lc, lp, pb, dummy bl LZMA_DECODE mov sp, r7 b .LLZMA_end .align 2 .LzmaParams: .long lzma_u_len, lzma_stack_adjust, lzma_c_len, lzma_properties .LLZMA_end: section LZMA_DECODE .real_start_ofLZMA_DECODE: // suppress silly warnings section LZMA_DEC10 #include "arch/arm/v4t/lzma_d_cs.S" /* vim:set ts=8 sw=8 et: */