diff --git a/native/src/Android.mk b/native/src/Android.mk index b972b372f..bee42029e 100644 --- a/native/src/Android.mk +++ b/native/src/Android.mk @@ -35,7 +35,6 @@ LOCAL_SRC_FILES := \ core/su/su_daemon.cpp \ zygisk/entry.cpp \ zygisk/main.cpp \ - zygisk/utils.cpp \ zygisk/hook.cpp \ zygisk/memory.cpp \ zygisk/native_bridge.cpp \ diff --git a/native/src/base/include/base.hpp b/native/src/base/include/base.hpp index 7ca70dc5f..01d350a58 100644 --- a/native/src/base/include/base.hpp +++ b/native/src/base/include/base.hpp @@ -4,7 +4,6 @@ #include "../files.hpp" #include "../misc.hpp" #include "../logging.hpp" -#include "../missing.hpp" #include "../base-rs.hpp" using rust::xpipe2; diff --git a/native/src/base/missing.hpp b/native/src/base/missing.hpp deleted file mode 100644 index c33f3138c..000000000 --- a/native/src/base/missing.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -static inline int fexecve(int fd, char* const* argv, char* const* envp) { - syscall(__NR_execveat, fd, "", argv, envp, AT_EMPTY_PATH); - if (errno == ENOSYS) { - char buf[256]; - ssprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd); - execve(buf, argv, envp); - } - return -1; -} diff --git a/native/src/base/xwrap.hpp b/native/src/base/xwrap.hpp index ce7a6dda8..917e300dc 100644 --- a/native/src/base/xwrap.hpp +++ b/native/src/base/xwrap.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/native/src/core/module.cpp b/native/src/core/module.cpp index 13a0f3ebd..48539f740 100644 --- a/native/src/core/module.cpp +++ b/native/src/core/module.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/native/src/zygisk/ptrace.cpp b/native/src/zygisk/ptrace.cpp deleted file mode 100644 index ae5bb00ed..000000000 --- a/native/src/zygisk/ptrace.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Original code: https://github.com/Chainfire/injectvm-binderjack/blob/master/app/src/main/jni/libinject/inject.cpp - * The code is heavily modified and sublicensed to GPLv3 for incorporating into Magisk. - * - * Copyright (c) 2015, Simone 'evilsocket' Margaritelli - * Copyright (c) 2015-2019, Jorrit 'Chainfire' Jongma - * Copyright (c) 2021, John 'topjohnwu' Wu - * - * See original LICENSE file from the original project for additional details: - * https://github.com/Chainfire/injectvm-binderjack/blob/master/LICENSE - */ - -/* - * NOTE: - * The code in this file was originally planned to be used for some features, - * but it turned out to be unsuitable for the task. However, this shall remain - * in our arsenal in case it may be used in the future. - */ - -#include -#include -#include -#include - -#include - -#include "zygisk.hpp" -#include "ptrace.hpp" - -using namespace std; - -#if defined(__arm__) -#define CPSR_T_MASK (1u << 5) -#define PARAMS_IN_REGS 4 -#elif defined(__aarch64__) -#define CPSR_T_MASK (1u << 5) -#define PARAMS_IN_REGS 8 -#define pt_regs user_pt_regs -#define uregs regs -#define ARM_pc pc -#define ARM_sp sp -#define ARM_cpsr pstate -#define ARM_lr regs[30] -#define ARM_r0 regs[0] -#endif - -bool _remote_read(int pid, uintptr_t addr, void *buf, size_t len) { - for (size_t i = 0; i < len; i += sizeof(long)) { - long data = xptrace(PTRACE_PEEKTEXT, pid, reinterpret_cast(addr + i)); - if (data < 0) - return false; - memcpy(static_cast(buf) + i, &data, std::min(len - i, sizeof(data))); - } - return true; -} - -bool _remote_write(int pid, uintptr_t addr, const void *buf, size_t len) { - for (size_t i = 0; i < len; i += sizeof(long)) { - long data = 0; - memcpy(&data, static_cast(buf) + i, std::min(len - i, sizeof(data))); - if (xptrace(PTRACE_POKETEXT, pid, reinterpret_cast(addr + i), data) < 0) - return false; - } - return true; -} - -// Get remote registers -#define remote_getregs(regs) _remote_getregs(pid, regs) -static void _remote_getregs(int pid, pt_regs *regs) { -#if defined(__LP64__) - uintptr_t regset = NT_PRSTATUS; - iovec iov{}; - iov.iov_base = regs; - iov.iov_len = sizeof(*regs); - xptrace(PTRACE_GETREGSET, pid, reinterpret_cast(regset), &iov); -#else - xptrace(PTRACE_GETREGS, pid, nullptr, regs); -#endif -} - -// Set remote registers -#define remote_setregs(regs) _remote_setregs(pid, regs) -static void _remote_setregs(int pid, pt_regs *regs) { -#if defined(__LP64__) - uintptr_t regset = NT_PRSTATUS; - iovec iov{}; - iov.iov_base = regs; - iov.iov_len = sizeof(*regs); - xptrace(PTRACE_SETREGSET, pid, reinterpret_cast(regset), &iov); -#else - xptrace(PTRACE_SETREGS, pid, nullptr, regs); -#endif -} - -uintptr_t remote_call_abi(int pid, uintptr_t func_addr, int nargs, va_list va) { - pt_regs regs, regs_bak; - - // Get registers and save a backup - remote_getregs(®s); - memcpy(®s_bak, ®s, sizeof(regs)); - - // ABI dependent: Setup stack and registers to perform the call - -#if defined(__arm__) || defined(__aarch64__) - // Fill R0-Rx with the first 4 (32-bit) or 8 (64-bit) parameters - for (int i = 0; (i < nargs) && (i < PARAMS_IN_REGS); ++i) { - regs.uregs[i] = va_arg(va, uintptr_t); - } - - // Push remaining parameters onto stack - if (nargs > PARAMS_IN_REGS) { - regs.ARM_sp -= sizeof(uintptr_t) * (nargs - PARAMS_IN_REGS); - uintptr_t stack = regs.ARM_sp; - for (int i = PARAMS_IN_REGS; i < nargs; ++i) { - uintptr_t arg = va_arg(va, uintptr_t); - remote_write(stack, &arg, sizeof(uintptr_t)); - stack += sizeof(uintptr_t); - } - } - - // Set return address - regs.ARM_lr = 0; - - // Set function address to call - regs.ARM_pc = func_addr; - - // Setup the current processor status register - if (regs.ARM_pc & 1u) { - // thumb - regs.ARM_pc &= (~1u); - regs.ARM_cpsr |= CPSR_T_MASK; - } else { - // arm - regs.ARM_cpsr &= ~CPSR_T_MASK; - } -#elif defined(__i386__) - // Push all params onto stack - regs.esp -= sizeof(uintptr_t) * nargs; - uintptr_t stack = regs.esp; - for (int i = 0; i < nargs; ++i) { - uintptr_t arg = va_arg(va, uintptr_t); - remote_write(stack, &arg, sizeof(uintptr_t)); - stack += sizeof(uintptr_t); - } - - // Push return address onto stack - uintptr_t ret_addr = 0; - regs.esp -= sizeof(uintptr_t); - remote_write(regs.esp, &ret_addr, sizeof(uintptr_t)); - - // Set function address to call - regs.eip = func_addr; -#elif defined(__x86_64__) - // Align, rsp - 8 must be a multiple of 16 at function entry point - uintptr_t space = sizeof(uintptr_t); - if (nargs > 6) - space += sizeof(uintptr_t) * (nargs - 6); - while (((regs.rsp - space - 8) & 0xF) != 0) - regs.rsp--; - - // Fill [RDI, RSI, RDX, RCX, R8, R9] with the first 6 parameters - for (int i = 0; (i < nargs) && (i < 6); ++i) { - uintptr_t arg = va_arg(va, uintptr_t); - switch (i) { - case 0: regs.rdi = arg; break; - case 1: regs.rsi = arg; break; - case 2: regs.rdx = arg; break; - case 3: regs.rcx = arg; break; - case 4: regs.r8 = arg; break; - case 5: regs.r9 = arg; break; - } - } - - // Push remaining parameters onto stack - if (nargs > 6) { - regs.rsp -= sizeof(uintptr_t) * (nargs - 6); - uintptr_t stack = regs.rsp; - for(int i = 6; i < nargs; ++i) { - uintptr_t arg = va_arg(va, uintptr_t); - remote_write(stack, &arg, sizeof(uintptr_t)); - stack += sizeof(uintptr_t); - } - } - - // Push return address onto stack - uintptr_t ret_addr = 0; - regs.rsp -= sizeof(uintptr_t); - remote_write(regs.rsp, &ret_addr, sizeof(uintptr_t)); - - // Set function address to call - regs.rip = func_addr; - - // may be needed - regs.rax = 0; - regs.orig_rax = 0; -#else -#error Unsupported ABI -#endif - - // Resume process to do the call - remote_setregs(®s); - xptrace(PTRACE_CONT, pid); - - // Catch SIGSEGV caused by the 0 return address - int status; - while (waitpid(pid, &status, __WALL | __WNOTHREAD) == pid) { - if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGSEGV)) - break; - xptrace(PTRACE_CONT, pid); - } - - // Get registers again for return value - remote_getregs(®s); - - // Restore registers - remote_setregs(®s_bak); - -#if defined(__arm__) || defined(__aarch64__) - return regs.ARM_r0; -#elif defined(__i386__) - return regs.eax; -#elif defined(__x86_64__) - return regs.rax; -#endif -} - -uintptr_t remote_call_vararg(int pid, uintptr_t addr, int nargs, ...) { - char lib_name[4096]; - auto off = get_function_off(getpid(), addr, lib_name); - if (off == 0) - return 0; - auto remote = get_function_addr(pid, lib_name, off); - if (remote == 0) - return 0; - va_list va; - va_start(va, nargs); - auto result = remote_call_abi(pid, remote, nargs, va); - va_end(va); - return result; -} diff --git a/native/src/zygisk/ptrace.hpp b/native/src/zygisk/ptrace.hpp deleted file mode 100644 index b4951a625..000000000 --- a/native/src/zygisk/ptrace.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -// Write bytes to the remote process at addr -bool _remote_write(int pid, uintptr_t addr, const void *buf, size_t len); -#define remote_write(...) _remote_write(pid, __VA_ARGS__) - -// Read bytes from the remote process at addr -bool _remote_read(int pid, uintptr_t addr, void *buf, size_t len); -#define remote_read(...) _remote_read(pid, __VA_ARGS__) - -// Call a remote function -// Arguments are expected to be only integer-like or pointer types -// as other more complex C ABIs are not implemented. -uintptr_t remote_call_abi(int pid, uintptr_t func_addr, int nargs, va_list va); - -// Find remote offset and invoke function -uintptr_t remote_call_vararg(int pid, uintptr_t addr, int nargs, ...); - -// C++ wrapper for auto argument counting and casting function pointers -template -static uintptr_t _remote_call(int pid, FuncPtr sym, Args && ...args) { - auto addr = reinterpret_cast(sym); - return remote_call_vararg(pid, addr, sizeof...(args), std::forward(args)...); -} -#define remote_call(...) _remote_call(pid, __VA_ARGS__) diff --git a/native/src/zygisk/utils.cpp b/native/src/zygisk/utils.cpp deleted file mode 100644 index 97cc5e2a3..000000000 --- a/native/src/zygisk/utils.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -#include "zygisk.hpp" -#include - -using namespace std; -static vector find_maps(const char *name) { - auto maps = lsplt::MapInfo::Scan(); - for (auto iter = maps.begin(); iter != maps.end();) { - if (iter->path != name) { - iter = maps.erase(iter); - } else { - ++iter; - } - } - return maps; -} - -void unmap_all(const char *name) { - auto maps = find_maps(name); - for (auto &info : maps) { - void *addr = reinterpret_cast(info.start); - size_t size = info.end - info.start; - if (info.perms & PROT_READ) { - // Make sure readable pages are still readable - void *dummy = xmmap(nullptr, size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - mremap(dummy, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, addr); - } else { - munmap(addr, size); - } - } -} - -void remap_all(const char *name) { - auto maps = find_maps(name); - for (auto &info : maps) { - void *addr = reinterpret_cast(info.start); - size_t size = info.end - info.start; - void *copy = xmmap(nullptr, size, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if ((info.perms & PROT_READ) == 0) { - mprotect(addr, size, PROT_READ); - } - memcpy(copy, addr, size); - mremap(copy, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, addr); - mprotect(addr, size, info.perms); - } -} - -uintptr_t get_function_off(int pid, uintptr_t addr, char *lib) { - for (auto &info : lsplt::MapInfo::Scan()) { - if (addr >= info.start && addr < info.end) { - if (lib) - strcpy(lib, info.path.data()); - return addr - info.start + info.offset; - } - } - return 0; -} - -uintptr_t get_function_addr(int pid, const char *lib, uintptr_t off) { - for (auto &info : lsplt::MapInfo::Scan()) { - if (info.path == lib && (info.perms & PROT_EXEC)) { - return info.start - info.offset + off; - } - } - return 0; -} diff --git a/native/src/zygisk/zygisk.hpp b/native/src/zygisk/zygisk.hpp index d32a8e99b..1895830a0 100644 --- a/native/src/zygisk/zygisk.hpp +++ b/native/src/zygisk/zygisk.hpp @@ -27,18 +27,6 @@ enum : int { #define ZLOGW(...) LOGW("zygisk32: " __VA_ARGS__) #endif -// Unmap all pages matching the name -void unmap_all(const char *name); - -// Remap all matching pages with anonymous pages -void remap_all(const char *name); - -// Get library name + offset (from start of ELF), given function address -uintptr_t get_function_off(int pid, uintptr_t addr, char *lib); - -// Get function address, given library name + offset -uintptr_t get_function_addr(int pid, const char *lib, uintptr_t off); - extern void *self_handle; void hook_functions();