1/* arm.v4t-wince.pe.S -- ARM/PE decompressor assembly startup (thumb mode) 2 3 This file is part of the UPX executable compressor. 4 5 Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer 6 Copyright (C) 1996-2020 Laszlo Molnar 7 Copyright (C) 2000-2020 John F. Reiser 8 All Rights Reserved. 9 10 UPX and the UCL library are free software; you can redistribute them 11 and/or modify them under the terms of the GNU General Public License as 12 published by the Free Software Foundation; either version 2 of 13 the License, or (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; see the file COPYING. 22 If not, write to the Free Software Foundation, Inc., 23 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24 25 Markus F.X.J. Oberhumer Laszlo Molnar 26 <markus@oberhumer.com> <ezerotven+github@gmail.com> 27 28 John F. Reiser 29 <jreiser@users.sourceforge.net> 30*/ 31 32#include "arch/arm/v4t/macros.S" 33 34// p_armpe.cpp uses some symbols, so they should be global 35 36 .globl SRC0 37 .globl DST0 38 .globl IATT 39 .globl ENTR 40 41 .arm 42 43 dst0 .req r8 @ global register 44 45section DllStart 46 cmp r1, #1 47 bne .Lstart_orig 48 49section ExeStart 50 stmfd sp!, {r0 - r11, lr} 51 52 @ access all pages in ARM mode - this seems to be required 53 @ otherwise the THUMB mode stuff fails 54 55 adr r3, SRC0 56 ldmia r3, {r5, r6, r7, r8, r9, r10, r11} @ r7=dst0 57 add r5, pc, #4096 @ r3=addr src0, r11=LoadLibraryW 58.L01: @ r10=GetProcAddressA, r9=CacheSync 59 ldr r6, [r7] 60 add r7, r7, #4096 61 cmp r7, r5 62 bls .L01 63 64 adr r4, ProcessAll + 1 65 mov lr, pc 66 bx r4 67 68 ldmfd sp!, {r0 - r11, lr} 69.Lstart_orig: 70 ldr ip, ENTR 71 bx ip 72 73SRC0: .long start_of_compressed 74SRCL: .long compressed_length 75DST0: .long start_of_uncompressed 76DSTL: .long uncompressed_length 77IATT: .long 0, 0, 0, 0 78ENTR: .long original_entry 79 80 .thumb 81 82ProcessAll: 83 ldmia r3!, {r0, r1, r2} @ r0=src0, r1=slen, r2=dst0, r3=addr dstl 84 mov dst0, r2 85 mov r4, r9 @ CacheSync 86 push {r4, lr} 87 88 @@ uncompress/unfilter/imports/relocs are copied here by the upx linker 89 90@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 91 92section Unfilter_0x50 93 buffer .req r0 94 addval .req r2 95 bufend .req r4 96 97 ldr buffer, .LFIBS 98 mov addval, #0 99 ldr bufend, .LFIBE 100 mov r5, #0x0f 101 mov r6, #0xff 102 lsl r6, #24 103 mvn r7, r6 104.Luf50_0: 105 cmp buffer, bufend 106 beq .Luf50_ret 107 108 ldr r3, [buffer] 109 lsr r1, r3, #24 110 and r1, r5 111 cmp r1, #0x0b 112 bne .Luf50_1 113 mov r1, r3 114 and r1, r6 115 sub r3, addval 116 and r3, r7 117 orr r3, r1 118 str r3, [buffer] 119 120.Luf50_1: 121 add buffer, #4 122 add addval, #1 123 b .Luf50_0 124 125 .unreq buffer 126 .unreq addval 127 .unreq bufend 128 129 .align 2 130S(FIBS):.long filter_buffer_start 131S(FIBE):.long filter_buffer_end 132 133.Luf50_ret: 134 135@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 136 137section Relocs 138 buffer .req r0 139 dest .req r1 140 addval .req r2 141 142 ldr buffer, .LBREL 143 mov addval, dst0 144 sub dest, addval, #4 145 146.Lreloc_loop: 147 ldrb r3, [buffer] 148 add buffer, #1 149 cmp r3, #0 150 beq .Lreloc_end 151 cmp r3, #0xf0 152 blo .Lreloc_add 153 154 mov r4, #0x0f 155 and r4, r3 156 ldrb r3, [buffer, #1] @ get_le16 157 lsl r4, #8 158 add r4, r3 159 ldrb r3, [buffer] 160 add buffer, #2 161 lsl r4, #8 162 add r3, r4 163 164.Lreloc_add: 165 add dest, r3 166 mov r5, #0 167 168.Lread_be32: 169 ldrb r3, [dest, r5] 170 lsl r4, #8 171 add r4, r3 172 add r5, #1 173 cmp r5, #4 174 bne .Lread_be32 175 176 add r4, addval 177 str r4, [dest] 178 b .Lreloc_loop 179 180 .align 2 181S(BREL):.long start_of_relocs 182 183.Lreloc_end: 184 185@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 186 187section Imports 188 imp .req r4 189 iat .req r5 190 dll .req r6 191 192.real_start_ofImports: // suppress silly warnings 193 mov r7, sp 194 sub sp, #508 195 sub sp, #508 196 sub sp, #508 197 sub sp, #508 198 ldr imp, .LBIMP 199.Lhi_loop1: 200 mov r0, imp 201 bl get_le32 202 beq .Lhi_end 203 204 ldr r1, .LONAM 205 add r0, r1 206 mov r1, sp 207.Lhi_copyname: 208 ldrb r2, [r0] 209 add r0, #1 210 strh r2, [r1] 211 add r1, #2 212 cmp r2, #0 213 bne .Lhi_copyname 214 215 mov r0, sp 216 bl LoadLibraryW 217 mov dll, r0 218 add r0, imp, #4 219 bl get_le32 220 mov iat, dst0 221 add iat, r0 222 add imp, #8 223 224.Lhi_gpa_loop: 225 ldrb r0, [imp] 226 add imp, #1 227 cmp r0, #1 228 bmi .Lhi_loop1 229 bne .Lhi_by_ord 230 231 mov r1, imp 232.Lhi_by_name: 233 ldrb r0, [imp] 234 add imp, #1 235 cmp r0, #0 236 bne .Lhi_by_name 237 b .Lhi_call_gpa 238 239.Lhi_by_ord: 240 ldrb r0, [imp] 241 ldrb r1, [imp, #1] 242 add imp, #2 243 lsl r1, #8 244 add r1, r0 245 246.Lhi_call_gpa: 247 mov r0, dll 248 bl GetProcAddressA 249 stmia iat!, {r0} 250 b .Lhi_gpa_loop 251 252 .unreq iat 253 .unreq imp 254 .unreq dll 255 256get_le32: @ optimized for size 257 mov r1, #3 258.Lg0: 259 ldrb r3, [r0, r1] 260 lsl r2, r2, #8 261 add r2, r2, r3 262 sub r1, #1 263 bpl .Lg0 264 mov r0, r2 @ sets the Z flag if zero 265 bx lr 266 267LoadLibraryW: 268 bx r11 269 270GetProcAddressA: 271 bx r10 272 273S(BIMP):.long start_of_imports 274S(ONAM):.long start_of_dll_names 275 276.Lhi_end: 277 mov sp, r7 278 279@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 280 281section ProcessEnd 282 pop {r1, r2} @ r1=CacheSync, r2=lr 283 mov r0, #4 @ parameter of CacheSync 284 mov lr, r2 285 bx r1 286 287@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 288 289#include "include/header.S" 290 291#define PURE_THUMB 1 292 293section .ucl_nrv2b_decompress_8 294#include "arch/arm/v4t/nrv2b_d8.S" 295#undef GETBIT 296#undef wrnk 297 298section Call2B 299 bl .thumb_nrv2b_d8 300 301 302section .ucl_nrv2e_decompress_8 303#include "arch/arm/v4t/nrv2e_d8.S" 304#undef GETBIT 305#undef wrnk 306 307section Call2E 308 bl .thumb_nrv2e_d8 309 310 311#if 0 312section .ucl_nrv2b_decompress_32 313#include "arch/arm/v4t/nrv2b_d32.S" 314#undef GETBIT 315#undef wrnk 316#endif 317 318 319#if 0 320section .ucl_nrv2e_decompress_32 321#include "arch/arm/v4t/nrv2e_d32.S" 322#undef GETBIT 323#undef wrnk 324#endif 325 326//////////////////////////////////////// 327 328section CallLZMA 329 // r0=src0, r1=slen, r2=dst0, r3=addr dstl 330 331 parb .req r3 332 para .req r4 333 parc .req r5 334 pard .req r6 335 336 adr r7, .LzmaParams 337 ldmia r7!, {parb, para, parc, pard} // load params 338 339 mov r7, sp // save stack 340 add para, sp 341 mov r1, #0 342.Lclearstack: 343 push {r1} 344 cmp sp, para 345 bne .Lclearstack 346 347 push {r2, parb, para} // out, outSize, &outSizeProcessed 348 add r3, para, #4 // &inSizeProcessed 349 mov r2, parc // inSize 350 add r1, r0, #2 // in 351 add r0, r3, #4 // &CLzmaDecoderState 352 str pard, [r0] // lc, lp, pb, dummy 353 bl LZMA_DECODE 354 mov sp, r7 355 b .LLZMA_end 356 357 .align 2 358.LzmaParams: 359 .long lzma_u_len, lzma_stack_adjust, lzma_c_len, lzma_properties 360 361.LLZMA_end: 362 363section LZMA_DECODE 364.real_start_ofLZMA_DECODE: // suppress silly warnings 365 366section LZMA_DEC10 367#include "arch/arm/v4t/lzma_d_cs.S" 368 369/* vim:set ts=8 sw=8 et: */ 370