Clean up codes

This commit is contained in:
LoveSy 2023-04-08 11:56:39 +08:00 committed by topjohnwu
parent 9fbd079560
commit cbc6d40b2c
9 changed files with 2 additions and 366 deletions

View File

@ -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 \

View File

@ -4,7 +4,6 @@
#include "../files.hpp"
#include "../misc.hpp"
#include "../logging.hpp"
#include "../missing.hpp"
#include "../base-rs.hpp"
using rust::xpipe2;

View File

@ -1,17 +0,0 @@
#pragma once
#include <sys/syscall.h>
#include <linux/fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
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;
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <poll.h>

View File

@ -1,4 +1,5 @@
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <map>
#include <utility>

View File

@ -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 <elf.h>
#include <sys/mount.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <base.hpp>
#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<void*>(addr + i));
if (data < 0)
return false;
memcpy(static_cast<uint8_t *>(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<const uint8_t *>(buf) + i, std::min(len - i, sizeof(data)));
if (xptrace(PTRACE_POKETEXT, pid, reinterpret_cast<void*>(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<void*>(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<void*>(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(&regs);
memcpy(&regs_bak, &regs, 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(&regs);
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(&regs);
// Restore registers
remote_setregs(&regs_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;
}

View File

@ -1,27 +0,0 @@
#pragma once
#include <stdint.h>
// 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<class FuncPtr, class ...Args>
static uintptr_t _remote_call(int pid, FuncPtr sym, Args && ...args) {
auto addr = reinterpret_cast<uintptr_t>(sym);
return remote_call_vararg(pid, addr, sizeof...(args), std::forward<Args>(args)...);
}
#define remote_call(...) _remote_call(pid, __VA_ARGS__)

View File

@ -1,68 +0,0 @@
#include <cinttypes>
#include <base.hpp>
#include "zygisk.hpp"
#include <lsplt.hpp>
using namespace std;
static vector<lsplt::MapInfo> 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<void *>(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<void *>(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;
}

View File

@ -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();