arm/pe: import handling updates (untested)

This commit is contained in:
László Molnár 2014-03-08 18:59:26 +01:00
parent 804a0ce601
commit 940341bc9d
8 changed files with 56 additions and 40 deletions

View File

@ -105,15 +105,20 @@ __packed_struct_end()
for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++) for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++)
{ {
im->oft = im->iat; 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"); // the order of procedure names below should match the
addKernelImport("COREDLL.DLL", "GetProcAddressA"); // assumptions of the assembly stubs
addKernelImport("COREDLL.DLL", "CacheSync"); // WARNING! these names are sorted alphanumerically by the ImportLinker
addKernelImport("CacheSync");
addKernelImport("GetProcAddressA");
addKernelImport("LoadLibraryW");
} }
void PackArmPe::processTls(Interval *) // pass 1 void PackArmPe::processTls(Interval *) // pass 1

View File

@ -46,6 +46,7 @@ public:
virtual const char *getFullName(const options_t *) const { return "arm-wince.pe"; } virtual const char *getFullName(const options_t *) const { return "arm-wince.pe"; }
virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getCompressionMethods(int method, int level) const;
virtual const int *getFilters() const; virtual const int *getFilters() const;
virtual void defineFilterSymbols(const Filter *) {}
virtual bool handleForceOption(); virtual bool handleForceOption();
virtual void callCompressWithFilters(Filter &, int filter_strategy, virtual void callCompressWithFilters(Filter &, int filter_strategy,
@ -65,8 +66,9 @@ protected:
virtual void buildLoader(const Filter *ft); virtual void buildLoader(const Filter *ft);
virtual Linker* newLinker() const; virtual Linker* newLinker() const;
virtual const char *kernelDll() const { return "coredll.dll"; }
virtual void processImports(unsigned, unsigned); virtual void processImports(unsigned, unsigned);
virtual void addKernelImports(); virtual void addStubImports();
virtual void processTls(Interval *); virtual void processTls(Interval *);

View File

@ -827,21 +827,29 @@ public:
tstr sdll(name_for_dll((const char*) dll, dll_name_id)); tstr sdll(name_for_dll((const char*) dll, dll_name_id));
return findSection(sdll, true)->offset; return findSection(sdll, true)->offset;
} }
template <typename C>
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 }; 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("LoadLibraryA");
addKernelImport("KERNEL32.DLL", "GetProcAddress"); addKernelImport("GetProcAddress");
if (!isdll) if (!isdll)
addKernelImport("KERNEL32.DLL", "ExitProcess"); addKernelImport("ExitProcess");
addKernelImport("KERNEL32.DLL", "VirtualProtect"); addKernelImport("VirtualProtect");
} }
void PeFile::processImports(unsigned myimport, unsigned) // pass 2 void PeFile::processImports(unsigned myimport, unsigned) // pass 2
@ -858,8 +866,6 @@ void PeFile::processImports(unsigned myimport, unsigned) // pass 2
template <typename LEXX, typename ord_mask_t> template <typename LEXX, typename ord_mask_t>
unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1
{ {
static const unsigned char kernel32dll[] = "KERNEL32.DLL";
unsigned dllnum = 0; unsigned dllnum = 0;
import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT)); import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT));
import_desc * const im_save = im; 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].iat = im->iat;
dlls[ic].lookupt = (LEXX*) (ibuf + (im->oft ? im->oft : im->iat)); dlls[ic].lookupt = (LEXX*) (ibuf + (im->oft ? im->oft : im->iat));
dlls[ic].original_position = ic; 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; 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)); ilinker = new ImportLinker(sizeof(LEXX));
// create the new import table // create the new import table
addKernelImports(); addStubImports();
for (ic = 0; ic < dllnum; ic++) 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 // for kernel32.dll we need to put all the imported
// ordinals into the output import table, as on // ordinals into the output import table, as on
// some versions of windows GetProcAddress does not resolve them // some versions of windows GetProcAddress does not resolve them
if (strcasecmp((const char*)idlls[ic]->name, "kernel32.dll"))
continue;
if (idlls[ic]->ordinal) if (idlls[ic]->ordinal)
for (LEXX *tarr = idlls[ic]->lookupt; *tarr; tarr++) for (LEXX *tarr = idlls[ic]->lookupt; *tarr; tarr++)
if (*tarr & ord_mask) if (*tarr & ord_mask)
{ {
ilinker->add(kernel32dll, *tarr & 0xffff); ilinker->add(kernelDll(), *tarr & 0xffff);
kernel32ordinal = true; kernel32ordinal = true;
} }
} }
else else if (!ilinker->hasDll(idlls[ic]->name))
{ {
if (idlls[ic]->ordinal) if (idlls[ic]->ordinal)
ilinker->add(idlls[ic]->name, 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) if (*tarr & ord_mask)
{ {
unsigned ord = *tarr & 0xffff; unsigned ord = *tarr & 0xffff;
if (idlls[ic]->isk32) if (idlls[ic]->isk32 && kernel32ordinal)
{ {
*ppi++ = 0xfe; // signed + odd parity *ppi++ = 0xfe; // signed + odd parity
set_le32(ppi, ilinker->getAddress(idlls[ic]->name, ord)); 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 // when the resource is put alone into section 3
const unsigned res_start = (ic + oam1) &~ oam1;; const unsigned res_start = (ic + oam1) &~ oam1;;
if (last_section_rsrc_only) if (last_section_rsrc_only)
callProcessResources(res, ic); callProcessResources(res, ic = res_start);
defineSymbols(ncsection, upxsection, sizeof(oh), defineSymbols(ncsection, upxsection, sizeof(oh),
identsize - identsplit, rel, s1addr); identsize - identsplit, rel, s1addr);

View File

@ -107,8 +107,9 @@ protected:
upx_byte *oimpdlls; upx_byte *oimpdlls;
unsigned soimpdlls; unsigned soimpdlls;
ImportLinker *ilinker; ImportLinker *ilinker;
void addKernelImport(const char *, const char *); virtual const char *kernelDll() const { return "kernel32.dll"; }
virtual void addKernelImports(); void addKernelImport(const char *);
virtual void addStubImports();
upx_uint64_t ilinkerGetAddress(const char *, const char *) const; upx_uint64_t ilinkerGetAddress(const char *, const char *) const;
virtual void processRelocs() = 0; virtual void processRelocs() = 0;

View File

@ -32,17 +32,17 @@
#define STUB_ARM_V4A_WINCE_PE_SIZE 15590 #define STUB_ARM_V4A_WINCE_PE_SIZE 15590
#define STUB_ARM_V4A_WINCE_PE_ADLER32 0x24a54147 #define STUB_ARM_V4A_WINCE_PE_ADLER32 0xb9b54141
#define STUB_ARM_V4A_WINCE_PE_CRC32 0x5f885b54 #define STUB_ARM_V4A_WINCE_PE_CRC32 0x28ab6b7c
unsigned char stub_arm_v4a_wince_pe[15590] = { 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 0x0210 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45,252, 64, 45,233,

View File

@ -32,8 +32,8 @@
#define STUB_ARM_V4T_WINCE_PE_SIZE 7542 #define STUB_ARM_V4T_WINCE_PE_SIZE 7542
#define STUB_ARM_V4T_WINCE_PE_ADLER32 0xc50af55d #define STUB_ARM_V4T_WINCE_PE_ADLER32 0xb60af55d
#define STUB_ARM_V4T_WINCE_PE_CRC32 0x99d633b4 #define STUB_ARM_V4T_WINCE_PE_CRC32 0x93e7ac4e
unsigned char stub_arm_v4t_wince_pe[7542] = { 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 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, /* 0x01b0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

View File

@ -81,7 +81,7 @@ section ExeStart
DINIT DINIT
adr r3, SRC0 adr r3, SRC0
ldmia r3!, {r0, r1, r2} @ r0=src0, r1=slen, r2=dst0, r3=addr dstl 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 mov dst0, r2
bl ProcessAll bl ProcessAll
@ -93,7 +93,7 @@ section ExeStart
ldr pc, ENTR ldr pc, ENTR
CacheSync: CacheSync:
ldr pc, IATT + 8 ldr pc, IATT
SRC0: .long start_of_compressed SRC0: .long start_of_compressed
SRCL: .long compressed_length SRCL: .long compressed_length
@ -330,10 +330,10 @@ get_le32: @ optimized for size
mov pc, lr mov pc, lr
LoadLibraryW: LoadLibraryW:
mov pc, r10 mov pc, r11
GetProcAddressA: GetProcAddressA:
mov pc, r11 mov pc, r10
BIMP: .long start_of_imports BIMP: .long start_of_imports
ONAM: .long start_of_dll_names ONAM: .long start_of_dll_names

View File

@ -54,8 +54,8 @@ section ExeStart
adr r3, SRC0 adr r3, SRC0
ldmia r3, {r5, r6, r7, r9, r10, r11, ip} @ r7=dst0 ldmia r3, {r5, r6, r7, r9, r10, r11, ip} @ r7=dst0
add r5, pc, #4096 @ r3=addr src0, r10=LoadLibraryW add r5, pc, #4096 @ r3=addr src0, ip=LoadLibraryW
.L01: @ r11=GetProcAddressA, ip=CacheSync .L01: @ r11=GetProcAddressA, r10=CacheSync
ldr r6, [r7] ldr r6, [r7]
add r7, r7, #4096 add r7, r7, #4096
cmp r7, r5 cmp r7, r5
@ -82,7 +82,7 @@ ENTR: .long original_entry
ProcessAll: ProcessAll:
ldmia r3!, {r0, r1, r2} @ r0=src0, r1=slen, r2=dst0, r3=addr dstl ldmia r3!, {r0, r1, r2} @ r0=src0, r1=slen, r2=dst0, r3=addr dstl
mov dst0, r2 mov dst0, r2
mov r4, ip @ CacheSync mov r4, r10 @ CacheSync
push {r4, lr} push {r4, lr}
@@ uncompress/unfilter/imports/relocs are copied here by the upx linker @@ uncompress/unfilter/imports/relocs are copied here by the upx linker
@ -265,7 +265,7 @@ get_le32: @ optimized for size
bx lr bx lr
LoadLibraryW: LoadLibraryW:
bx r10 bx ip
GetProcAddressA: GetProcAddressA:
bx r11 bx r11