Many changes for ELF shared libraries on Linux and Android
Handling more than 2 PT_LOAD (and thus more than 1 executable PT_LOAD) required extensive changes. But the bonus is the infrastructure to support a different (de-)compression algorithm for each PT_LOAD. https://github.com/upx/upx/issues/341 i386 .so decompression https://github.com/upx/upx/issues/609 armv7 .so on Android https://github.com/upx/upx/issues/625 amd64 .so execution https://github.com/upx/upx/issues/654 armv7 .exe Not yet: .so on MIPS, PowerPC, PowerPC64
This commit is contained in:
committed by
Markus F.X.J. Oberhumer
parent
fa56a1d9cd
commit
adb0ca8250
+51
-1
@@ -463,6 +463,7 @@ static int s_ct24arm_be(Filter *f)
|
||||
// 26-bit ARM calltrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#if 1 //{ old reliable
|
||||
#define CT26ARM_LE(f, cond, addvalue, get, set) \
|
||||
byte *b = f->buf; \
|
||||
byte *b_end = b + f->buf_len - 4; \
|
||||
@@ -479,7 +480,6 @@ static int s_ct24arm_be(Filter *f)
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
|
||||
#define ARMCT_COND (((b[3] & 0x7C) == 0x14))
|
||||
|
||||
static int f_ct26arm_le(Filter *f)
|
||||
@@ -497,6 +497,56 @@ static int s_ct26arm_le(Filter *f)
|
||||
CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy)
|
||||
}
|
||||
|
||||
#else //}{ new enhanced but DIFFERENT; need new filter type!
|
||||
|
||||
static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1
|
||||
{
|
||||
upx_byte *b = f->buf; // will be incremented
|
||||
upx_byte *const b_end = b + f->buf_len - 4;
|
||||
do {
|
||||
unsigned const a = b - f->buf;
|
||||
int const d = dir * (f->addvalue + (a >> 2));
|
||||
unsigned const v = get_le32(f->buf); // the 32-bit instruction
|
||||
if (0x05 == (0x1f & (v >> 26))) { // b, bl
|
||||
f->lastcall = a;
|
||||
if (dir) set_le26(b, v + d);
|
||||
f->calls++;
|
||||
}
|
||||
else if ( (0x54 == (v >> 24) ) // b.cond
|
||||
|| (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz}
|
||||
) {
|
||||
f->lastcall = a;
|
||||
if (dir) set_le19_5(b, (v >> 5) + d);
|
||||
f->calls++;
|
||||
}
|
||||
else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
|
||||
f->lastcall = a;
|
||||
if (dir) set_le14_5(b, (v >> 5) + d);
|
||||
f->calls++;
|
||||
}
|
||||
b += 4;
|
||||
} while (b < b_end);
|
||||
if (f->lastcall) f->lastcall += 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f_CTarm64_le(Filter *f)
|
||||
{
|
||||
return CTarm64(f, 1);
|
||||
}
|
||||
|
||||
static int u_CTarm64_le(Filter *f)
|
||||
{
|
||||
return CTarm64(f, -1);
|
||||
}
|
||||
|
||||
static int s_CTarm64_le(Filter *f)
|
||||
{
|
||||
return CTarm64(f, 0);
|
||||
}
|
||||
|
||||
#endif //}
|
||||
|
||||
#undef CT26ARM_LE
|
||||
#undef ARMCT_COND
|
||||
|
||||
|
||||
@@ -228,8 +228,13 @@ umin(unsigned const a, unsigned const b)
|
||||
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
||||
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
||||
|
||||
#if 1 //{ old reliable
|
||||
// 26-bit calltrick for arm64
|
||||
{ 0x52, 8, 0x03ffffff, f_ct26arm_le, u_ct26arm_le, s_ct26arm_le },
|
||||
#else //}{ new enhanced, but needs new filter id
|
||||
// 26-bit calltrick for arm64; also 19-bit and 14-bit
|
||||
{ 0x52, 8, 0x03ffffff, f_CTarm64_le, u_CTarm64_le, s_CTarm64_le },
|
||||
#endif //}
|
||||
|
||||
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
||||
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||
|
||||
Reference in New Issue
Block a user