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:
John Reiser
2023-03-04 17:37:25 -08:00
committed by Markus F.X.J. Oberhumer
parent fa56a1d9cd
commit adb0ca8250
121 changed files with 15796 additions and 6036 deletions
+51 -1
View File
@@ -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
+5
View File
@@ -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 },