arm64 filter, relocation, defineSymbols
modified: Makefile modified: bele.h modified: filter/ct.h modified: filteri.cpp modified: linker.cpp modified: miniacc.h modified: p_lx_elf.cpp modified: stub/arm64-linux.elf-entry.h modified: stub/src/arm64-linux.elf-entry.S
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# build configuration options for this Makefile
|
# build configuration options for this Makefile
|
||||||
BUILD_TYPE_DEBUG ?= 0
|
BUILD_TYPE_DEBUG ?= 1
|
||||||
BUILD_TYPE_SANITIZE ?= 0
|
BUILD_TYPE_SANITIZE ?= 0
|
||||||
BUILD_USE_DEPEND ?= 1
|
BUILD_USE_DEPEND ?= 1
|
||||||
|
|
||||||
|
|||||||
+18
@@ -142,6 +142,24 @@ inline void set_le24(void *p, unsigned v)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline unsigned get_le26(const void *p)
|
||||||
|
{
|
||||||
|
#if defined(ACC_UA_GET_LE26)
|
||||||
|
return ACC_UA_GET_LE26(p);
|
||||||
|
#else
|
||||||
|
return acc_ua_get_le26(p);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_le26(void *p, unsigned v)
|
||||||
|
{
|
||||||
|
#if defined(ACC_UA_SET_LE26)
|
||||||
|
ACC_UA_SET_LE26(p, v);
|
||||||
|
#else
|
||||||
|
acc_ua_set_le26(p, v);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline unsigned get_le32(const void *p)
|
inline unsigned get_le32(const void *p)
|
||||||
{
|
{
|
||||||
#if defined(ACC_UA_GET_LE32)
|
#if defined(ACC_UA_GET_LE32)
|
||||||
|
|||||||
@@ -459,4 +459,45 @@ static int s_ct24arm_be(Filter *f)
|
|||||||
#undef CT24ARM_BE
|
#undef CT24ARM_BE
|
||||||
#undef ARMCT_COND
|
#undef ARMCT_COND
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// 26-bit ARM calltrick ("naive")
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define CT26ARM_LE(f, cond, addvalue, get, set) \
|
||||||
|
upx_byte *b = f->buf; \
|
||||||
|
upx_byte *b_end = b + f->buf_len - 4; \
|
||||||
|
do { \
|
||||||
|
if (cond) \
|
||||||
|
{ \
|
||||||
|
unsigned a = (unsigned) (b - f->buf); \
|
||||||
|
f->lastcall = a; \
|
||||||
|
set(b, get(b) + (addvalue)); \
|
||||||
|
f->calls++; \
|
||||||
|
} \
|
||||||
|
b += 4; \
|
||||||
|
} while (b < b_end); \
|
||||||
|
if (f->lastcall) f->lastcall += 4; \
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
#define ARMCT_COND (((b[3] & 0x7C) == 0x14))
|
||||||
|
|
||||||
|
static int f_ct26arm_le(Filter *f)
|
||||||
|
{
|
||||||
|
CT26ARM_LE(f, ARMCT_COND, a / 4 + f->addvalue, get_le26, set_le26)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int u_ct26arm_le(Filter *f)
|
||||||
|
{
|
||||||
|
CT26ARM_LE(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le26, set_le26)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int s_ct26arm_le(Filter *f)
|
||||||
|
{
|
||||||
|
CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CT26ARM_LE
|
||||||
|
#undef ARMCT_COND
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
@@ -228,6 +228,9 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
||||||
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
||||||
|
|
||||||
|
// 26-bit calltrick for arm64
|
||||||
|
{ 0x52, 8, 0x03ffffff, f_ct26arm_le, u_ct26arm_le, s_ct26arm_le },
|
||||||
|
|
||||||
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
// 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 },
|
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||||
{ 0x81, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
{ 0x81, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||||
|
|||||||
+6
-2
@@ -541,7 +541,7 @@ void ElfLinker::alignWithByte(unsigned len, unsigned char b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::relocate1(const Relocation *rel, upx_byte *, upx_uint64_t, const char *) {
|
void ElfLinker::relocate1(const Relocation *rel, upx_byte *, upx_uint64_t, const char *) {
|
||||||
internal_error("unknown relocation type '%s\n", rel->type);
|
internal_error("unknown relocation type '%s\n'", rel->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -600,7 +600,6 @@ void ElfLinkerARM64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
|
|||||||
if (!strncmp(type, "PREL", 4)) {
|
if (!strncmp(type, "PREL", 4)) {
|
||||||
value -= rel->section->offset + rel->offset;
|
value -= rel->section->offset + rel->offset;
|
||||||
type += 4;
|
type += 4;
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(type, "16"))
|
if (!strcmp(type, "16"))
|
||||||
set_le16(location, get_le16(location) + value);
|
set_le16(location, get_le16(location) + value);
|
||||||
@@ -608,6 +607,11 @@ void ElfLinkerARM64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
|
|||||||
set_le32(location, get_le32(location) + value);
|
set_le32(location, get_le32(location) + value);
|
||||||
else if (!strcmp(type, "64"))
|
else if (!strcmp(type, "64"))
|
||||||
set_le64(location, get_le64(location) + value);
|
set_le64(location, get_le64(location) + value);
|
||||||
|
} else if (!strcmp(type, "ABS32") == 0) {
|
||||||
|
set_le32(location, get_le32(location) + value);
|
||||||
|
} else if (!strcmp(type, "ABS64") == 0) {
|
||||||
|
set_le64(location, get_le64(location) + value);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
super::relocate1(rel, location, value, type);
|
super::relocate1(rel, location, value, type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5065,9 +5065,11 @@ ACCLIB_EXTERN(void, acc_ua_set_be24) (acc_hvoid_p, acc_uint32l_t);
|
|||||||
ACCLIB_EXTERN(void, acc_ua_set_be32) (acc_hvoid_p, acc_uint32l_t);
|
ACCLIB_EXTERN(void, acc_ua_set_be32) (acc_hvoid_p, acc_uint32l_t);
|
||||||
ACCLIB_EXTERN(unsigned, acc_ua_get_le16) (const acc_hvoid_p);
|
ACCLIB_EXTERN(unsigned, acc_ua_get_le16) (const acc_hvoid_p);
|
||||||
ACCLIB_EXTERN(acc_uint32l_t, acc_ua_get_le24) (const acc_hvoid_p);
|
ACCLIB_EXTERN(acc_uint32l_t, acc_ua_get_le24) (const acc_hvoid_p);
|
||||||
|
ACCLIB_EXTERN(acc_uint32l_t, acc_ua_get_le26) (const acc_hvoid_p);
|
||||||
ACCLIB_EXTERN(acc_uint32l_t, acc_ua_get_le32) (const acc_hvoid_p);
|
ACCLIB_EXTERN(acc_uint32l_t, acc_ua_get_le32) (const acc_hvoid_p);
|
||||||
ACCLIB_EXTERN(void, acc_ua_set_le16) (acc_hvoid_p, unsigned);
|
ACCLIB_EXTERN(void, acc_ua_set_le16) (acc_hvoid_p, unsigned);
|
||||||
ACCLIB_EXTERN(void, acc_ua_set_le24) (acc_hvoid_p, acc_uint32l_t);
|
ACCLIB_EXTERN(void, acc_ua_set_le24) (acc_hvoid_p, acc_uint32l_t);
|
||||||
|
ACCLIB_EXTERN(void, acc_ua_set_le26) (acc_hvoid_p, acc_uint32l_t);
|
||||||
ACCLIB_EXTERN(void, acc_ua_set_le32) (acc_hvoid_p, acc_uint32l_t);
|
ACCLIB_EXTERN(void, acc_ua_set_le32) (acc_hvoid_p, acc_uint32l_t);
|
||||||
#if defined(acc_int64l_t)
|
#if defined(acc_int64l_t)
|
||||||
ACCLIB_EXTERN(acc_uint64l_t, acc_ua_get_be64) (const acc_hvoid_p);
|
ACCLIB_EXTERN(acc_uint64l_t, acc_ua_get_be64) (const acc_hvoid_p);
|
||||||
@@ -6057,6 +6059,12 @@ ACCLIB_PUBLIC(acc_uint32l_t, acc_ua_get_le24) (const acc_hvoid_p p)
|
|||||||
const acc_hbyte_p b = ACC_CCAST(const acc_hbyte_p, p);
|
const acc_hbyte_p b = ACC_CCAST(const acc_hbyte_p, p);
|
||||||
return ACC_ICONV(acc_uint32l_t, b[0]) | (ACC_ICONV(acc_uint32l_t, b[1]) << 8) | (ACC_ICONV(acc_uint32l_t, b[2]) << 16);
|
return ACC_ICONV(acc_uint32l_t, b[0]) | (ACC_ICONV(acc_uint32l_t, b[1]) << 8) | (ACC_ICONV(acc_uint32l_t, b[2]) << 16);
|
||||||
}
|
}
|
||||||
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_ua_get_le26) (const acc_hvoid_p p)
|
||||||
|
{
|
||||||
|
const acc_hbyte_p b = ACC_CCAST(const acc_hbyte_p, p);
|
||||||
|
return ACC_ICONV(acc_uint32l_t, b[0] ) | ( ACC_ICONV(acc_uint32l_t, b[1]) << 8) |
|
||||||
|
(ACC_ICONV(acc_uint32l_t, b[2]) << 16) | (((ACC_ICONV(acc_uint32l_t, b[3]) & 3)<< 24));
|
||||||
|
}
|
||||||
ACCLIB_PUBLIC(acc_uint32l_t, acc_ua_get_le32) (const acc_hvoid_p p)
|
ACCLIB_PUBLIC(acc_uint32l_t, acc_ua_get_le32) (const acc_hvoid_p p)
|
||||||
{
|
{
|
||||||
#if defined(ACC_UA_GET_LE32)
|
#if defined(ACC_UA_GET_LE32)
|
||||||
@@ -6083,6 +6091,14 @@ ACCLIB_PUBLIC(void, acc_ua_set_le24) (acc_hvoid_p p, acc_uint32l_t v)
|
|||||||
b[1] = ACC_ICONV(unsigned char, (v >> 8) & 0xff);
|
b[1] = ACC_ICONV(unsigned char, (v >> 8) & 0xff);
|
||||||
b[2] = ACC_ICONV(unsigned char, (v >> 16) & 0xff);
|
b[2] = ACC_ICONV(unsigned char, (v >> 16) & 0xff);
|
||||||
}
|
}
|
||||||
|
ACCLIB_PUBLIC(void, acc_ua_set_le26) (acc_hvoid_p p, acc_uint32l_t v)
|
||||||
|
{
|
||||||
|
acc_hbyte_p b = ACC_PCAST(acc_hbyte_p, p);
|
||||||
|
b[0] = ACC_ICONV(unsigned char, (v >> 0) & 0xff);
|
||||||
|
b[1] = ACC_ICONV(unsigned char, (v >> 8) & 0xff);
|
||||||
|
b[2] = ACC_ICONV(unsigned char, (v >> 16) & 0xff);
|
||||||
|
b[3] = ACC_ICONV(unsigned char, (v >> 24) & 0x03) | (0xFC & b[3]);
|
||||||
|
}
|
||||||
ACCLIB_PUBLIC(void, acc_ua_set_le32) (acc_hvoid_p p, acc_uint32l_t v)
|
ACCLIB_PUBLIC(void, acc_ua_set_le32) (acc_hvoid_p p, acc_uint32l_t v)
|
||||||
{
|
{
|
||||||
#if defined(ACC_UA_SET_LE32)
|
#if defined(ACC_UA_SET_LE32)
|
||||||
|
|||||||
+46
-80
@@ -705,7 +705,7 @@ int const *
|
|||||||
PackLinuxElf64arm::getFilters() const
|
PackLinuxElf64arm::getFilters() const
|
||||||
{
|
{
|
||||||
static const int filters[] = {
|
static const int filters[] = {
|
||||||
0x4A,
|
0x52,
|
||||||
FT_END };
|
FT_END };
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
@@ -1118,85 +1118,6 @@ PackLinuxElf64amd::defineSymbols(Filter const *)
|
|||||||
//linker->dumpSymbols(); // debug
|
//linker->dumpSymbols(); // debug
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PackLinuxElf64arm::defineSymbols(Filter const *)
|
|
||||||
{
|
|
||||||
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
|
||||||
|
|
||||||
// We want to know if compressed data, plus stub, plus a couple pages,
|
|
||||||
// will fit below the uncompressed program in memory. But we don't
|
|
||||||
// know the final total compressed size yet, so use the uncompressed
|
|
||||||
// size (total over all PT_LOAD64) as an upper bound.
|
|
||||||
unsigned len = 0;
|
|
||||||
upx_uint64_t lo_va_user = ~0ull; // infinity
|
|
||||||
for (int j= e_phnum; --j>=0; ) {
|
|
||||||
if (PT_LOAD64 == get_te32(&phdri[j].p_type)) {
|
|
||||||
len += (unsigned)get_te64(&phdri[j].p_filesz);
|
|
||||||
upx_uint64_t const va = get_te64(&phdri[j].p_vaddr);
|
|
||||||
if (va < lo_va_user) {
|
|
||||||
lo_va_user = va;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lsize = /*getLoaderSize()*/ 64 * 1024; // XXX: upper bound; avoid circularity
|
|
||||||
upx_uint64_t lo_va_stub = get_te64(&elfout.phdr[0].p_vaddr);
|
|
||||||
upx_uint64_t adrc;
|
|
||||||
upx_uint64_t adrm;
|
|
||||||
upx_uint64_t adru;
|
|
||||||
upx_uint64_t adrx;
|
|
||||||
unsigned cntc;
|
|
||||||
unsigned lenm;
|
|
||||||
unsigned lenu;
|
|
||||||
len += (7&-lsize) + lsize;
|
|
||||||
is_big = (lo_va_user < (lo_va_stub + len + 2*page_size));
|
|
||||||
if (is_big && ehdri.ET_EXEC==get_te16(&ehdri.e_type)) {
|
|
||||||
set_te64( &elfout.ehdr.e_entry,
|
|
||||||
get_te64(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);
|
|
||||||
set_te64(&elfout.phdr[0].p_vaddr, lo_va_user);
|
|
||||||
set_te64(&elfout.phdr[0].p_paddr, lo_va_user);
|
|
||||||
lo_va_stub = lo_va_user;
|
|
||||||
adrc = lo_va_stub;
|
|
||||||
adrm = getbrk(phdri, e_phnum);
|
|
||||||
adru = page_mask & (~page_mask + adrm); // round up to page boundary
|
|
||||||
adrx = adru + hlen;
|
|
||||||
lenm = page_size + len;
|
|
||||||
lenu = page_size + len;
|
|
||||||
cntc = len >> 3; // over-estimate; corrected at runtime
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
adrm = lo_va_stub + len;
|
|
||||||
adrc = adrm;
|
|
||||||
adru = lo_va_stub;
|
|
||||||
adrx = lo_va_stub + hlen;
|
|
||||||
lenm = page_size;
|
|
||||||
lenu = page_size + len;
|
|
||||||
cntc = 0;
|
|
||||||
}
|
|
||||||
adrm = page_mask & (~page_mask + adrm); // round up to page boundary
|
|
||||||
adrc = page_mask & (~page_mask + adrc); // round up to page boundary
|
|
||||||
|
|
||||||
//linker->defineSymbol("ADRX", adrx); // compressed input for eXpansion
|
|
||||||
ACC_UNUSED(adrx);
|
|
||||||
|
|
||||||
// For actual moving, we need the true count, which depends on sz_pack2
|
|
||||||
// and is not yet known. So the runtime stub detects "no move"
|
|
||||||
// if adrm==adrc, and otherwise uses actual sz_pack2 to compute cntc.
|
|
||||||
//linker->defineSymbol("CNTC", cntc); // count for copy
|
|
||||||
ACC_UNUSED(cntc);
|
|
||||||
|
|
||||||
linker->defineSymbol("LENU", lenu); // len for unmap
|
|
||||||
linker->defineSymbol("ADRC", adrc); // addr for copy
|
|
||||||
//linker->defineSymbol("ADRU", adru); // addr for unmap
|
|
||||||
ACC_UNUSED(adru);
|
|
||||||
#define EI_NIDENT 16 /* <elf.h> */
|
|
||||||
linker->defineSymbol("JMPU", EI_NIDENT -4 + lo_va_user); // unmap trampoline
|
|
||||||
#undef EI_NIDENT
|
|
||||||
linker->defineSymbol("LENM", lenm); // len for map
|
|
||||||
linker->defineSymbol("ADRM", adrm); // addr for map
|
|
||||||
|
|
||||||
//linker->dumpSymbols(); // debug
|
|
||||||
}
|
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/i386-linux.elf-entry.h"
|
#include "stub/i386-linux.elf-entry.h"
|
||||||
static const
|
static const
|
||||||
@@ -3329,6 +3250,51 @@ void PackLinuxElf32armBe::defineSymbols(Filter const *ft)
|
|||||||
ARM_defineSymbols(ft);
|
ARM_defineSymbols(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackLinuxElf64arm::defineSymbols(Filter const * /*ft*/)
|
||||||
|
{
|
||||||
|
lsize = /*getLoaderSize()*/ 4 * 1024; // upper bound; avoid circularity
|
||||||
|
unsigned lo_va_user = ~0u; // infinity
|
||||||
|
for (int j= e_phnum; --j>=0; ) {
|
||||||
|
if (PT_LOAD64 == get_te64(&phdri[j].p_type)) {
|
||||||
|
unsigned const va = get_te64(&phdri[j].p_vaddr);
|
||||||
|
if (va < lo_va_user) {
|
||||||
|
lo_va_user = va;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsigned lo_va_stub = get_te64(&elfout.phdr[0].p_vaddr);
|
||||||
|
unsigned adrc = 0; // init: pacify c++-analyzer
|
||||||
|
unsigned adrm = 0; // init: pacify c++-analyzer
|
||||||
|
|
||||||
|
is_big = true; // kernel disallows mapping below 0x8000.
|
||||||
|
if (is_big) {
|
||||||
|
set_te64( &elfout.ehdr.e_entry, linker->getSymbolOffset("_start") +
|
||||||
|
get_te64(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);
|
||||||
|
set_te64(&elfout.phdr[0].p_vaddr, lo_va_user);
|
||||||
|
set_te64(&elfout.phdr[0].p_paddr, lo_va_user);
|
||||||
|
lo_va_stub = lo_va_user;
|
||||||
|
adrc = lo_va_stub;
|
||||||
|
adrm = getbrk(phdri, e_phnum);
|
||||||
|
}
|
||||||
|
adrc = page_mask & (~page_mask + adrc); // round up to page boundary
|
||||||
|
adrm = page_mask & (~page_mask + adrm); // round up to page boundary
|
||||||
|
adrm += page_size; // Try: hole so that kernel does not extend the brk(0)
|
||||||
|
linker->defineSymbol("ADRM", adrm); // addr for map
|
||||||
|
|
||||||
|
linker->defineSymbol("CPR0", 4+ linker->getSymbolOffset("cpr0"));
|
||||||
|
linker->defineSymbol("LENF", 4+ linker->getSymbolOffset("end_decompress"));
|
||||||
|
ACC_UNUSED(adrc);
|
||||||
|
|
||||||
|
#define MAP_PRIVATE 2 /* UNIX standard */
|
||||||
|
#define MAP_FIXED 0x10 /* UNIX standard */
|
||||||
|
#define MAP_ANONYMOUS 0x20 /* UNIX standard */
|
||||||
|
#define MAP_PRIVANON 3 /* QNX anonymous private memory */
|
||||||
|
unsigned mflg = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||||
|
//if (ARM_is_QNX())
|
||||||
|
// mflg = MAP_PRIVANON;
|
||||||
|
linker->defineSymbol("MFLG", mflg);
|
||||||
|
}
|
||||||
|
|
||||||
void PackLinuxElf32mipseb::defineSymbols(Filter const * /*ft*/)
|
void PackLinuxElf32mipseb::defineSymbols(Filter const * /*ft*/)
|
||||||
{
|
{
|
||||||
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define STUB_ARM64_LINUX_ELF_ENTRY_SIZE 5317
|
#define STUB_ARM64_LINUX_ELF_ENTRY_SIZE 5317
|
||||||
#define STUB_ARM64_LINUX_ELF_ENTRY_ADLER32 0x85fe782d
|
#define STUB_ARM64_LINUX_ELF_ENTRY_ADLER32 0x69217770
|
||||||
#define STUB_ARM64_LINUX_ELF_ENTRY_CRC32 0x6307b5a0
|
#define STUB_ARM64_LINUX_ELF_ENTRY_CRC32 0xb10ced92
|
||||||
|
|
||||||
unsigned char stub_arm64_linux_elf_entry[5317] = {
|
unsigned char stub_arm64_linux_elf_entry[5317] = {
|
||||||
/* 0x0000 */ 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
/* 0x0000 */ 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
@@ -41,9 +41,9 @@ unsigned char stub_arm64_linux_elf_entry[5317] = {
|
|||||||
/* 0x0020 */ 0, 0, 0, 0, 0, 0, 0, 0, 8, 13, 0, 0, 0, 0, 0, 0,
|
/* 0x0020 */ 0, 0, 0, 0, 0, 0, 0, 0, 8, 13, 0, 0, 0, 0, 0, 0,
|
||||||
/* 0x0030 */ 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 64, 0, 17, 0, 14, 0,
|
/* 0x0030 */ 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 64, 0, 17, 0, 14, 0,
|
||||||
/* 0x0040 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
/* 0x0040 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* 0x0050 */ 0, 0, 0, 0, 76,255,255, 16,129, 41, 64, 41,139, 53, 65, 41,
|
/* 0x0050 */ 0, 0, 0, 0, 0, 0, 32,212, 44,255,255, 16,129, 41, 64, 41,
|
||||||
/* 0x0060 */ 130, 9, 64,249,107, 1, 12,139, 74, 1, 12,139, 99, 1, 64,185,
|
/* 0x0060 */ 139, 53, 65, 41,107, 1, 12,139, 74, 1, 12,139, 99, 1, 64,185,
|
||||||
/* 0x0070 */ 137, 1, 1,203, 33, 0, 3, 11,224, 3, 2,170, 33, 4, 64,145,
|
/* 0x0070 */ 137, 1, 1,203, 33, 0, 3, 11,128, 9, 64,249, 33, 4, 64,145,
|
||||||
/* 0x0080 */ 3, 0,128, 82, 3, 0,130, 82,224,135,189,169,226, 15, 1,169,
|
/* 0x0080 */ 3, 0,128, 82, 3, 0,130, 82,224,135,189,169,226, 15, 1,169,
|
||||||
/* 0x0090 */ 237, 19, 0,249,226, 0,128, 82,163, 1, 28, 50, 5, 0,128,210,
|
/* 0x0090 */ 237, 19, 0,249,226, 0,128, 82,163, 1, 28, 50, 5, 0,128,210,
|
||||||
/* 0x00a0 */ 4, 0,128, 18,200, 27,128, 82, 1, 0, 0,212,192, 3, 95,214,
|
/* 0x00a0 */ 4, 0,128, 18,200, 27,128, 82, 1, 0, 0,212,192, 3, 95,214,
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ mflg:
|
|||||||
.long MFLG // MAP_{PRIVATE|ANONYMOUS} // QNX vs linux
|
.long MFLG // MAP_{PRIVATE|ANONYMOUS} // QNX vs linux
|
||||||
.xword ADRM // dst for map
|
.xword ADRM // dst for map
|
||||||
_start: .globl _start
|
_start: .globl _start
|
||||||
//// nop; bkpt
|
brk #0
|
||||||
/* Get some pages: enough
|
/* Get some pages: enough
|
||||||
to duplicate the entire compressed PT_LOAD, plus 1 page, located just after
|
to duplicate the entire compressed PT_LOAD, plus 1 page, located just after
|
||||||
the brk() of the _un_compressed program. The address is pre-calculated
|
the brk() of the _un_compressed program. The address is pre-calculated
|
||||||
@@ -89,13 +89,12 @@ _start: .globl _start
|
|||||||
adr x12,start_params -4 // &sz_pack2
|
adr x12,start_params -4 // &sz_pack2
|
||||||
ldp w1,w10,[x12] // w1= sz_pack2; w10= LENF
|
ldp w1,w10,[x12] // w1= sz_pack2; w10= LENF
|
||||||
ldp w11,w13,[x12,#2*4] // w11= CPRO; w13= MFLG
|
ldp w11,w13,[x12,#2*4] // w11= CPRO; w13= MFLG
|
||||||
ldr x2,[x12,#4*4] // x2= ADRM
|
|
||||||
add x11,x11,x12 // cpr0
|
add x11,x11,x12 // cpr0
|
||||||
add x10,x10,x12 // end_decompress
|
add x10,x10,x12 // end_decompress
|
||||||
ldr w3,[x11,# sz_unc]
|
ldr w3,[x11,# sz_unc]
|
||||||
sub x9,x12,x1 // &our_Elf64_Ehdr
|
sub x9,x12,x1 // &our_Elf64_Ehdr
|
||||||
add w1,w1,w3 // sz_pack2 + cpr0.sz_unc
|
add w1,w1,w3 // sz_pack2 + cpr0.sz_unc
|
||||||
mov x0,x2 // ADRM
|
ldr x0,[x12,#4*4] // ADRM
|
||||||
add x1,x1,# PAGE_SIZE
|
add x1,x1,# PAGE_SIZE
|
||||||
section LUNMP000
|
section LUNMP000
|
||||||
mov w3,#0<<12 // 0-page crumb
|
mov w3,#0<<12 // 0-page crumb
|
||||||
|
|||||||
Reference in New Issue
Block a user