From 940341bc9d2bfdb77c35be72f6f58e5d1f37e62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Moln=C3=A1r?= Date: Sat, 8 Mar 2014 18:59:26 +0100 Subject: [PATCH] arm/pe: import handling updates (untested) --- src/p_armpe.cpp | 15 ++++++++----- src/p_armpe.h | 4 +++- src/pefile.cpp | 38 ++++++++++++++++++++------------- src/pefile.h | 5 +++-- src/stub/arm.v4a-wince.pe.h | 10 ++++----- src/stub/arm.v4t-wince.pe.h | 8 +++---- src/stub/src/arm.v4a-wince.pe.S | 8 +++---- src/stub/src/arm.v4t-wince.pe.S | 8 +++---- 8 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/p_armpe.cpp b/src/p_armpe.cpp index 718a499d..99d8e41d 100644 --- a/src/p_armpe.cpp +++ b/src/p_armpe.cpp @@ -105,15 +105,20 @@ __packed_struct_end() for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++) { im->oft = im->iat; - im->iat = im == (import_desc*) oimpdlls ? iat_off : iat_off + 12; + bool is_coredll = strcasecmp(kernelDll(), (char*) oimpdlls + + im->dllname - myimport) == 0; + im->iat = is_coredll ? iat_off : iat_off + 12; } } -void PackArmPe::addKernelImports() +void PackArmPe::addStubImports() { - addKernelImport("COREDLL.DLL", "LoadLibraryW"); - addKernelImport("COREDLL.DLL", "GetProcAddressA"); - addKernelImport("COREDLL.DLL", "CacheSync"); + // the order of procedure names below should match the + // assumptions of the assembly stubs + // WARNING! these names are sorted alphanumerically by the ImportLinker + addKernelImport("CacheSync"); + addKernelImport("GetProcAddressA"); + addKernelImport("LoadLibraryW"); } void PackArmPe::processTls(Interval *) // pass 1 diff --git a/src/p_armpe.h b/src/p_armpe.h index 4b535c39..4e9aac78 100644 --- a/src/p_armpe.h +++ b/src/p_armpe.h @@ -46,6 +46,7 @@ public: virtual const char *getFullName(const options_t *) const { return "arm-wince.pe"; } virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getFilters() const; + virtual void defineFilterSymbols(const Filter *) {} virtual bool handleForceOption(); virtual void callCompressWithFilters(Filter &, int filter_strategy, @@ -65,8 +66,9 @@ protected: virtual void buildLoader(const Filter *ft); virtual Linker* newLinker() const; + virtual const char *kernelDll() const { return "coredll.dll"; } virtual void processImports(unsigned, unsigned); - virtual void addKernelImports(); + virtual void addStubImports(); virtual void processTls(Interval *); diff --git a/src/pefile.cpp b/src/pefile.cpp index 58a4f36a..f47fc24f 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -827,21 +827,29 @@ public: tstr sdll(name_for_dll((const char*) dll, dll_name_id)); return findSection(sdll, true)->offset; } + + template + upx_uint64_t hasDll(const C *dll) const + { + ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" + tstr sdll(name_for_dll((const char*) dll, dll_name_id)); + return findSection(sdll, false) != NULL; + } }; const char PeFile::ImportLinker::zeros[sizeof(import_desc)] = { 0 }; -void PeFile::addKernelImport(const char *dll, const char *name) +void PeFile::addKernelImport(const char *name) { - ilinker->add(dll, name); + ilinker->add(kernelDll(), name); } -void PeFile::addKernelImports() +void PeFile::addStubImports() { - addKernelImport("KERNEL32.DLL", "LoadLibraryA"); - addKernelImport("KERNEL32.DLL", "GetProcAddress"); + addKernelImport("LoadLibraryA"); + addKernelImport("GetProcAddress"); if (!isdll) - addKernelImport("KERNEL32.DLL", "ExitProcess"); - addKernelImport("KERNEL32.DLL", "VirtualProtect"); + addKernelImport("ExitProcess"); + addKernelImport("VirtualProtect"); } void PeFile::processImports(unsigned myimport, unsigned) // pass 2 @@ -858,8 +866,6 @@ void PeFile::processImports(unsigned myimport, unsigned) // pass 2 template unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 { - static const unsigned char kernel32dll[] = "KERNEL32.DLL"; - unsigned dllnum = 0; import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT)); import_desc * const im_save = im; @@ -914,7 +920,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 dlls[ic].iat = im->iat; dlls[ic].lookupt = (LEXX*) (ibuf + (im->oft ? im->oft : im->iat)); dlls[ic].original_position = ic; - dlls[ic].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0; + dlls[ic].isk32 = strcasecmp(kernelDll(), (const char*)dlls[ic].name) == 0; soimport += strlen(dlls[ic].name) + 1 + 4; @@ -946,7 +952,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 ilinker = new ImportLinker(sizeof(LEXX)); // create the new import table - addKernelImports(); + addStubImports(); for (ic = 0; ic < dllnum; ic++) { @@ -955,15 +961,17 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 // for kernel32.dll we need to put all the imported // ordinals into the output import table, as on // some versions of windows GetProcAddress does not resolve them + if (strcasecmp((const char*)idlls[ic]->name, "kernel32.dll")) + continue; if (idlls[ic]->ordinal) for (LEXX *tarr = idlls[ic]->lookupt; *tarr; tarr++) if (*tarr & ord_mask) { - ilinker->add(kernel32dll, *tarr & 0xffff); + ilinker->add(kernelDll(), *tarr & 0xffff); kernel32ordinal = true; } } - else + else if (!ilinker->hasDll(idlls[ic]->name)) { if (idlls[ic]->ordinal) ilinker->add(idlls[ic]->name, idlls[ic]->ordinal); @@ -994,7 +1002,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 if (*tarr & ord_mask) { unsigned ord = *tarr & 0xffff; - if (idlls[ic]->isk32) + if (idlls[ic]->isk32 && kernel32ordinal) { *ppi++ = 0xfe; // signed + odd parity set_le32(ppi, ilinker->getAddress(idlls[ic]->name, ord)); @@ -2350,7 +2358,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, // when the resource is put alone into section 3 const unsigned res_start = (ic + oam1) &~ oam1;; if (last_section_rsrc_only) - callProcessResources(res, ic); + callProcessResources(res, ic = res_start); defineSymbols(ncsection, upxsection, sizeof(oh), identsize - identsplit, rel, s1addr); diff --git a/src/pefile.h b/src/pefile.h index b5be3f81..ffc8f2d0 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -107,8 +107,9 @@ protected: upx_byte *oimpdlls; unsigned soimpdlls; ImportLinker *ilinker; - void addKernelImport(const char *, const char *); - virtual void addKernelImports(); + virtual const char *kernelDll() const { return "kernel32.dll"; } + void addKernelImport(const char *); + virtual void addStubImports(); upx_uint64_t ilinkerGetAddress(const char *, const char *) const; virtual void processRelocs() = 0; diff --git a/src/stub/arm.v4a-wince.pe.h b/src/stub/arm.v4a-wince.pe.h index fc77d5fb..3b05ed39 100644 --- a/src/stub/arm.v4a-wince.pe.h +++ b/src/stub/arm.v4a-wince.pe.h @@ -32,17 +32,17 @@ #define STUB_ARM_V4A_WINCE_PE_SIZE 15590 -#define STUB_ARM_V4A_WINCE_PE_ADLER32 0x24a54147 -#define STUB_ARM_V4A_WINCE_PE_CRC32 0x5f885b54 +#define STUB_ARM_V4A_WINCE_PE_ADLER32 0xb9b54141 +#define STUB_ARM_V4A_WINCE_PE_CRC32 0x28ab6b7c unsigned char stub_arm_v4a_wince_pe[15590] = { /* 0x0000 */ 127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0010 */ 1, 0, 40, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0020 */ 156, 15, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 40, 0, /* 0x0030 */ 33, 0, 30, 0, 1, 0, 81,227, 7, 0, 0, 26,255, 79, 45,233, -/* 0x0040 */ 32, 48,143,226, 7, 0,179,232, 16, 12,147,232, 2,144,160,225, +/* 0x0040 */ 32, 48,143,226, 7, 0,179,232, 16, 14,147,232, 2,144,160,225, /* 0x0050 */ 18, 0, 0,235, 4, 0,160,227, 8, 0, 0,235,255, 79,189,232, -/* 0x0060 */ 32,240,159,229, 20,240,159,229, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x0060 */ 32,240,159,229, 12,240,159,229, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0070 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0080 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 45,233, /* 0x0090 */ 0,128,189,232, 60, 0,159,229, 0, 32,160,227, 56,192,159,229, @@ -66,7 +66,7 @@ unsigned char stub_arm_v4a_wince_pe[15590] = { /* 0x01b0 */ 1, 0,212,228, 1, 16,212,228, 1, 20,128,224, 6, 0,160,225, /* 0x01c0 */ 41, 0, 0,235, 4, 0,133,228, 17, 0, 0,234, 3, 32,160,227, /* 0x01d0 */ 2, 48,208,231, 1, 32, 82,226, 1, 20,131,224, 34, 0, 0, 90, -/* 0x01e0 */ 1, 0,176,225, 14,240,160,225, 10,240,160,225, 11,240,160,225, +/* 0x01e0 */ 1, 0,176,225, 14,240,160,225, 11,240,160,225, 10,240,160,225, /* 0x01f0 */ 0, 0, 0, 0, 0, 0, 0, 0, 2,219,141,226, 85, 80, 88, 33, /* 0x0200 */ 161,216,208,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0210 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45,252, 64, 45,233, diff --git a/src/stub/arm.v4t-wince.pe.h b/src/stub/arm.v4t-wince.pe.h index 8826982c..0230947f 100644 --- a/src/stub/arm.v4t-wince.pe.h +++ b/src/stub/arm.v4t-wince.pe.h @@ -32,8 +32,8 @@ #define STUB_ARM_V4T_WINCE_PE_SIZE 7542 -#define STUB_ARM_V4T_WINCE_PE_ADLER32 0xc50af55d -#define STUB_ARM_V4T_WINCE_PE_CRC32 0x99d633b4 +#define STUB_ARM_V4T_WINCE_PE_ADLER32 0xb60af55d +#define STUB_ARM_V4T_WINCE_PE_CRC32 0x93e7ac4e unsigned char stub_arm_v4t_wince_pe[7542] = { /* 0x0000 */ 127, 69, 76, 70, 1, 1, 1, 97, 0, 0, 0, 0, 0, 0, 0, 0, @@ -45,7 +45,7 @@ unsigned char stub_arm_v4t_wince_pe[7542] = { /* 0x0060 */ 15,224,160,225, 20,255, 47,225,255, 79,189,232, 32,192,159,229, /* 0x0070 */ 28,255, 47,225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0080 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 0x0090 */ 0, 0, 0, 0, 0, 0, 0, 0, 7,203,145, 70,100, 70, 16,181, +/* 0x0090 */ 0, 0, 0, 0, 0, 0, 0, 0, 7,203,145, 70, 84, 70, 16,181, /* 0x00a0 */ 11, 72, 0, 34, 11, 76, 15, 37,255, 38, 54, 6,247, 67,160, 66, /* 0x00b0 */ 18,208, 3,104, 25, 14, 41, 64, 11, 41, 5,209, 25, 28, 49, 64, /* 0x00c0 */ 155, 26, 59, 64, 11, 67, 3, 96, 4, 48, 1, 50,239,231, 0, 0, @@ -60,7 +60,7 @@ unsigned char stub_arm_v4t_wince_pe[7542] = { /* 0x0150 */ 8, 52, 32,120, 1, 52, 1, 40,228,212, 5,209, 33, 28, 32,120, /* 0x0160 */ 1, 52, 0, 40,251,209, 4,224, 32,120, 97,120, 2, 52, 9, 2, /* 0x0170 */ 9, 24, 48, 28, 0,240, 57,248, 1,197,234,231, 3, 33, 67, 92, -/* 0x0180 */ 18, 2,210, 24, 1, 57,250,213, 16, 28,112, 71, 80, 71, 88, 71, +/* 0x0180 */ 18, 2,210, 24, 1, 57,250,213, 16, 28,112, 71, 96, 71, 88, 71, /* 0x0190 */ 0, 0, 0, 0, 0, 0, 0, 0,189, 70, 6,188, 4, 32,150, 70, /* 0x01a0 */ 8, 71, 85, 80, 88, 33,161,216,208,213, 0, 0, 0, 0, 0, 0, /* 0x01b0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/stub/src/arm.v4a-wince.pe.S b/src/stub/src/arm.v4a-wince.pe.S index fb3554e7..abc1c0dc 100644 --- a/src/stub/src/arm.v4a-wince.pe.S +++ b/src/stub/src/arm.v4a-wince.pe.S @@ -81,7 +81,7 @@ section ExeStart DINIT adr r3, SRC0 ldmia r3!, {r0, r1, r2} @ r0=src0, r1=slen, r2=dst0, r3=addr dstl - ldmia r3, {r4, r10, r11} @ r10=LoadLibraryW, r11=GetProcAddressA + ldmia r3, {r4, r9, r10, r11} @ r11=LoadLibraryW, r10=GetProcAddressA mov dst0, r2 bl ProcessAll @@ -93,7 +93,7 @@ section ExeStart ldr pc, ENTR CacheSync: - ldr pc, IATT + 8 + ldr pc, IATT SRC0: .long start_of_compressed SRCL: .long compressed_length @@ -330,10 +330,10 @@ get_le32: @ optimized for size mov pc, lr LoadLibraryW: - mov pc, r10 + mov pc, r11 GetProcAddressA: - mov pc, r11 + mov pc, r10 BIMP: .long start_of_imports ONAM: .long start_of_dll_names diff --git a/src/stub/src/arm.v4t-wince.pe.S b/src/stub/src/arm.v4t-wince.pe.S index 03e934e1..b8e395b7 100644 --- a/src/stub/src/arm.v4t-wince.pe.S +++ b/src/stub/src/arm.v4t-wince.pe.S @@ -54,8 +54,8 @@ section ExeStart adr r3, SRC0 ldmia r3, {r5, r6, r7, r9, r10, r11, ip} @ r7=dst0 - add r5, pc, #4096 @ r3=addr src0, r10=LoadLibraryW -.L01: @ r11=GetProcAddressA, ip=CacheSync + add r5, pc, #4096 @ r3=addr src0, ip=LoadLibraryW +.L01: @ r11=GetProcAddressA, r10=CacheSync ldr r6, [r7] add r7, r7, #4096 cmp r7, r5 @@ -82,7 +82,7 @@ ENTR: .long original_entry ProcessAll: ldmia r3!, {r0, r1, r2} @ r0=src0, r1=slen, r2=dst0, r3=addr dstl mov dst0, r2 - mov r4, ip @ CacheSync + mov r4, r10 @ CacheSync push {r4, lr} @@ uncompress/unfilter/imports/relocs are copied here by the upx linker @@ -265,7 +265,7 @@ get_le32: @ optimized for size bx lr LoadLibraryW: - bx r10 + bx ip GetProcAddressA: bx r11