You've already forked ZygiskNext
mirror of
https://github.com/Dr-TSNG/ZygiskNext.git
synced 2025-08-27 23:46:34 +00:00
refine code
This commit is contained in:
@@ -94,7 +94,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnregisterHandler(EventHandler &handler) {
|
||||
[[maybe_unused]] bool UnregisterHandler(EventHandler &handler) {
|
||||
if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, handler.GetFd(), nullptr) == -1) {
|
||||
PLOGE("failed to del event handler");
|
||||
return false;
|
||||
@@ -149,7 +149,7 @@ struct SocketHandler : public EventHandler {
|
||||
return sock_fd_;
|
||||
}
|
||||
|
||||
void HandleEvent(EventLoop &loop, uint32_t event) override {
|
||||
void HandleEvent(EventLoop &loop, uint32_t) override {
|
||||
struct [[gnu::packed]] MsgHead {
|
||||
Command cmd;
|
||||
int length;
|
||||
@@ -346,7 +346,7 @@ public:
|
||||
return signal_fd_;
|
||||
}
|
||||
|
||||
void HandleEvent(EventLoop &loop, uint32_t event) override {
|
||||
void HandleEvent(EventLoop &, uint32_t) override {
|
||||
for (;;) {
|
||||
ssize_t s = read(signal_fd_, &fdsi, sizeof(fdsi));
|
||||
if (s == -1) {
|
||||
@@ -602,7 +602,7 @@ void send_control_command(Command cmd) {
|
||||
if (nsend == -1) {
|
||||
err(EXIT_FAILURE, "send");
|
||||
} else if (nsend != sizeof(cmd)) {
|
||||
printf("send %ld != %ld\n", nsend, sizeof(cmd));
|
||||
printf("send %zu != %zu\n", nsend, sizeof(cmd));
|
||||
exit(1);
|
||||
}
|
||||
printf("command sent\n");
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <signal.h>
|
||||
#include <sys/system_properties.h>
|
||||
#include <string>
|
||||
#include <cinttypes>
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
bool inject_on_main(int pid, const char *lib_path) {
|
||||
@@ -23,42 +25,42 @@ bool inject_on_main(int pid, const char *lib_path) {
|
||||
struct user_regs_struct regs{}, backup{};
|
||||
auto map = MapInfo::Scan(std::to_string(pid));
|
||||
if (!get_regs(pid, regs)) return false;
|
||||
auto arg = reinterpret_cast<uintptr_t *>(regs.REG_SP);
|
||||
LOGD("kernel argument %p %s", arg, get_addr_mem_region(map, arg).c_str());
|
||||
auto arg = static_cast<uintptr_t>(regs.REG_SP);
|
||||
LOGV("kernel argument %" PRIxPTR " %s", arg, get_addr_mem_region(map, arg).c_str());
|
||||
int argc;
|
||||
auto argv = reinterpret_cast<char **>(reinterpret_cast<uintptr_t *>(arg) + 1);
|
||||
LOGD("argv %p", argv);
|
||||
LOGV("argv %p", argv);
|
||||
read_proc(pid, arg, &argc, sizeof(argc));
|
||||
LOGD("argc %d", argc);
|
||||
LOGV("argc %d", argc);
|
||||
auto envp = argv + argc + 1;
|
||||
LOGD("envp %p", envp);
|
||||
LOGV("envp %p", envp);
|
||||
auto p = envp;
|
||||
while (true) {
|
||||
uintptr_t *buf;
|
||||
read_proc(pid, (uintptr_t *) p, &buf, sizeof(buf));
|
||||
read_proc(pid, (uintptr_t) p, &buf, sizeof(buf));
|
||||
if (buf != nullptr) ++p;
|
||||
else break;
|
||||
}
|
||||
++p;
|
||||
auto auxv = reinterpret_cast<ElfW(auxv_t) *>(p);
|
||||
LOGD("auxv %p %s", auxv, get_addr_mem_region(map, auxv).c_str());
|
||||
LOGV("auxv %p %s", auxv, get_addr_mem_region(map, (uintptr_t) auxv).c_str());
|
||||
auto v = auxv;
|
||||
void *entry_addr = nullptr;
|
||||
void *addr_of_entry_addr = nullptr;
|
||||
uintptr_t entry_addr = 0;
|
||||
uintptr_t addr_of_entry_addr = 0;
|
||||
while (true) {
|
||||
ElfW(auxv_t) buf;
|
||||
read_proc(pid, (uintptr_t *) v, &buf, sizeof(buf));
|
||||
read_proc(pid, (uintptr_t) v, &buf, sizeof(buf));
|
||||
if (buf.a_type == AT_ENTRY) {
|
||||
entry_addr = reinterpret_cast<void *>(buf.a_un.a_val);
|
||||
addr_of_entry_addr = reinterpret_cast<char *>(v) + offsetof(ElfW(auxv_t), a_un);
|
||||
LOGD("entry address %p %s (v=%p, entry_addr=%p)", entry_addr,
|
||||
get_addr_mem_region(map, entry_addr).c_str(), v, addr_of_entry_addr);
|
||||
entry_addr = (uintptr_t) buf.a_un.a_val;
|
||||
addr_of_entry_addr = (uintptr_t) v + offsetof(ElfW(auxv_t), a_un);
|
||||
LOGV("entry address %" PRIxPTR " %s (entry=%" PRIxPTR ", entry_addr=%" PRIxPTR ")", entry_addr,
|
||||
get_addr_mem_region(map, entry_addr).c_str(), (uintptr_t) v, addr_of_entry_addr);
|
||||
break;
|
||||
}
|
||||
if (buf.a_type == AT_NULL) break;
|
||||
v++;
|
||||
}
|
||||
if (entry_addr == nullptr) {
|
||||
if (entry_addr == 0) {
|
||||
LOGE("failed to get entry");
|
||||
return false;
|
||||
}
|
||||
@@ -66,13 +68,13 @@ bool inject_on_main(int pid, const char *lib_path) {
|
||||
// Replace the program entry with an invalid address
|
||||
// For arm32 compatibility, we set the last bit to the same as the entry address
|
||||
uintptr_t break_addr = (-0x05ec1cff & ~1) | ((uintptr_t) entry_addr & 1);
|
||||
if (!write_proc(pid, (uintptr_t *) addr_of_entry_addr, &break_addr, sizeof(break_addr))) return false;
|
||||
if (!write_proc(pid, (uintptr_t) addr_of_entry_addr, &break_addr, sizeof(break_addr))) return false;
|
||||
ptrace(PTRACE_CONT, pid, 0, 0);
|
||||
int status;
|
||||
wait_for_trace(pid, &status, __WALL);
|
||||
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSEGV) {
|
||||
if (!get_regs(pid, regs)) return false;
|
||||
if ((regs.REG_IP & ~1) != (break_addr & ~1)) {
|
||||
if (static_cast<uintptr_t>(regs.REG_IP & ~1) != (break_addr & ~1)) {
|
||||
LOGE("stopped at unknown addr %p", (void *) regs.REG_IP);
|
||||
return false;
|
||||
}
|
||||
@@ -80,7 +82,7 @@ bool inject_on_main(int pid, const char *lib_path) {
|
||||
LOGD("stopped at entry");
|
||||
|
||||
// restore entry address
|
||||
if (!write_proc(pid, (uintptr_t *) addr_of_entry_addr, &entry_addr, sizeof(entry_addr))) return false;
|
||||
if (!write_proc(pid, (uintptr_t) addr_of_entry_addr, &entry_addr, sizeof(entry_addr))) return false;
|
||||
|
||||
// backup registers
|
||||
memcpy(&backup, ®s, sizeof(regs));
|
||||
@@ -119,11 +121,13 @@ bool inject_on_main(int pid, const char *lib_path) {
|
||||
args.clear();
|
||||
args.push_back(dlerror_str_addr);
|
||||
auto dlerror_len = remote_call(pid, regs, (uintptr_t) strlen_addr, (uintptr_t) libc_return_addr, args);
|
||||
LOGD("dlerror len %ld", dlerror_len);
|
||||
if (dlerror_len <= 0) return false;
|
||||
if (dlerror_len <= 0) {
|
||||
LOGE("dlerror len <= 0");
|
||||
return false;
|
||||
}
|
||||
std::string err;
|
||||
err.resize(dlerror_len + 1, 0);
|
||||
read_proc(pid, (uintptr_t*) dlerror_str_addr, err.data(), dlerror_len);
|
||||
read_proc(pid, (uintptr_t) dlerror_str_addr, err.data(), dlerror_len);
|
||||
LOGE("dlerror info %s", err.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -102,8 +102,8 @@ std::vector<MapInfo> MapInfo::Scan(const std::string& pid) {
|
||||
return info;
|
||||
}
|
||||
|
||||
ssize_t write_proc(int pid, uintptr_t *remote_addr, const void *buf, size_t len) {
|
||||
LOGD("write to remote addr %p size %zu", remote_addr, len);
|
||||
ssize_t write_proc(int pid, uintptr_t remote_addr, const void *buf, size_t len) {
|
||||
LOGV("write to remote addr %" PRIxPTR " size %zu", remote_addr, len);
|
||||
struct iovec local{
|
||||
.iov_base = (void *) buf,
|
||||
.iov_len = len
|
||||
@@ -115,13 +115,13 @@ ssize_t write_proc(int pid, uintptr_t *remote_addr, const void *buf, size_t len)
|
||||
auto l = process_vm_writev(pid, &local, 1, &remote, 1, 0);
|
||||
if (l == -1) {
|
||||
PLOGE("process_vm_writev");
|
||||
} else if (l != len) {
|
||||
} else if (static_cast<size_t>(l) != len) {
|
||||
LOGW("not fully written: %zu, excepted %zu", l, len);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
ssize_t read_proc(int pid, uintptr_t *remote_addr, void *buf, size_t len) {
|
||||
ssize_t read_proc(int pid, uintptr_t remote_addr, void *buf, size_t len) {
|
||||
struct iovec local{
|
||||
.iov_base = (void *) buf,
|
||||
.iov_len = len
|
||||
@@ -133,7 +133,7 @@ ssize_t read_proc(int pid, uintptr_t *remote_addr, void *buf, size_t len) {
|
||||
auto l = process_vm_readv(pid, &local, 1, &remote, 1, 0);
|
||||
if (l == -1) {
|
||||
PLOGE("process_vm_readv");
|
||||
} else if (l != len) {
|
||||
} else if (static_cast<size_t>(l) != len) {
|
||||
LOGW("not fully read: %zu, excepted %zu", l, len);
|
||||
}
|
||||
return l;
|
||||
@@ -177,9 +177,9 @@ bool set_regs(int pid, struct user_regs_struct ®s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string get_addr_mem_region(std::vector<MapInfo> &info, void *addr) {
|
||||
std::string get_addr_mem_region(std::vector<MapInfo> &info, uintptr_t addr) {
|
||||
for (auto &map: info) {
|
||||
if (map.start <= (uintptr_t) addr && map.end > (uintptr_t) addr) {
|
||||
if (map.start <= addr && map.end > addr) {
|
||||
auto s = std::string(map.path);
|
||||
s += ' ';
|
||||
s += map.perms & PROT_READ ? 'r' : '-';
|
||||
@@ -248,24 +248,24 @@ void align_stack(struct user_regs_struct ®s, long preserve) {
|
||||
regs.REG_SP = (regs.REG_SP - preserve) & ~0xf;
|
||||
}
|
||||
|
||||
void *push_string(int pid, struct user_regs_struct ®s, const char *str) {
|
||||
uintptr_t push_string(int pid, struct user_regs_struct ®s, const char *str) {
|
||||
auto len = strlen(str) + 1;
|
||||
regs.REG_SP -= len;
|
||||
align_stack(regs);
|
||||
auto addr = reinterpret_cast<uintptr_t *>(regs.REG_SP);
|
||||
auto addr = static_cast<uintptr_t>(regs.REG_SP);
|
||||
if (!write_proc(pid, addr, str, len)) {
|
||||
LOGE("failed to write string %s", str);
|
||||
}
|
||||
LOGD("pushed string %p", addr);
|
||||
LOGD("pushed string %" PRIxPTR, addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
uintptr_t remote_call(int pid, struct user_regs_struct ®s, uintptr_t func_addr, uintptr_t return_addr,
|
||||
std::vector<long> &args) {
|
||||
align_stack(regs);
|
||||
LOGD("call %d args", args.size());
|
||||
LOGV("calling remote function %" PRIxPTR " args %zu", func_addr, args.size());
|
||||
for (auto &a: args) {
|
||||
LOGD("arg %p", (void *) a);
|
||||
LOGV("arg %p", (void *) a);
|
||||
}
|
||||
#if defined(__x86_64__)
|
||||
if (args.size() >= 1) {
|
||||
@@ -289,12 +289,12 @@ uintptr_t remote_call(int pid, struct user_regs_struct ®s, uintptr_t func_add
|
||||
if (args.size() > 6) {
|
||||
auto remain = (args.size() - 6) * sizeof(long);
|
||||
align_stack(regs, remain);
|
||||
if (!write_proc(pid, (uintptr_t *) regs.REG_SP, args.data(), remain)) {
|
||||
if (!write_proc(pid, (uintptr_t) regs.REG_SP, args.data(), remain)) {
|
||||
LOGE("failed to push arguments");
|
||||
}
|
||||
}
|
||||
regs.REG_SP -= sizeof(long);
|
||||
if (!write_proc(pid, (uintptr_t *) regs.REG_SP, &return_addr, sizeof(return_addr))) {
|
||||
if (!write_proc(pid, (uintptr_t) regs.REG_SP, &return_addr, sizeof(return_addr))) {
|
||||
LOGE("failed to write return addr");
|
||||
}
|
||||
regs.REG_IP = func_addr;
|
||||
@@ -302,34 +302,34 @@ uintptr_t remote_call(int pid, struct user_regs_struct ®s, uintptr_t func_add
|
||||
if (args.size() > 0) {
|
||||
auto remain = (args.size()) * sizeof(long);
|
||||
align_stack(regs, remain);
|
||||
if (!write_proc(pid, (uintptr_t *)regs.REG_SP, args.data(), remain)) {
|
||||
if (!write_proc(pid, (uintptr_t) regs.REG_SP, args.data(), remain)) {
|
||||
LOGE("failed to push arguments");
|
||||
}
|
||||
}
|
||||
regs.REG_SP -= sizeof(long);
|
||||
if (!write_proc(pid, (uintptr_t*) regs.REG_SP, &return_addr, sizeof(return_addr))) {
|
||||
if (!write_proc(pid, (uintptr_t) regs.REG_SP, &return_addr, sizeof(return_addr))) {
|
||||
LOGE("failed to write return addr");
|
||||
}
|
||||
regs.REG_IP = func_addr;
|
||||
#elif defined(__aarch64__)
|
||||
for (int i = 0; i < args.size() && i < 8; i++) {
|
||||
for (size_t i = 0; i < args.size() && i < 8; i++) {
|
||||
regs.regs[i] = args[i];
|
||||
}
|
||||
if (args.size() > 8) {
|
||||
auto remain = (args.size() - 8) * sizeof(long);
|
||||
align_stack(regs, remain);
|
||||
write_proc(pid, (uintptr_t *)regs.REG_SP, args.data(), remain);
|
||||
write_proc(pid, (uintptr_t)regs.REG_SP, args.data(), remain);
|
||||
}
|
||||
regs.regs[30] = return_addr;
|
||||
regs.REG_IP = func_addr;
|
||||
#elif defined(__arm__)
|
||||
for (int i = 0; i < args.size() && i < 4; i++) {
|
||||
for (size_t i = 0; i < args.size() && i < 4; i++) {
|
||||
regs.uregs[i] = args[i];
|
||||
}
|
||||
if (args.size() > 4) {
|
||||
auto remain = (args.size() - 4) * sizeof(long);
|
||||
align_stack(regs, remain);
|
||||
write_proc(pid, (uintptr_t *)regs.REG_SP, args.data(), remain);
|
||||
write_proc(pid, (uintptr_t)regs.REG_SP, args.data(), remain);
|
||||
}
|
||||
regs.uregs[14] = return_addr;
|
||||
regs.REG_IP = func_addr;
|
||||
@@ -353,7 +353,7 @@ uintptr_t remote_call(int pid, struct user_regs_struct ®s, uintptr_t func_add
|
||||
return 0;
|
||||
}
|
||||
if (WSTOPSIG(status) == SIGSEGV) {
|
||||
if (regs.REG_IP != return_addr) {
|
||||
if (static_cast<uintptr_t>(regs.REG_IP) != return_addr) {
|
||||
LOGE("wrong return addr %p", (void *) regs.REG_IP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,15 +60,15 @@ struct MapInfo {
|
||||
#define user_regs_struct user_regs
|
||||
#endif
|
||||
|
||||
ssize_t write_proc(int pid, uintptr_t *remote_addr, const void *buf, size_t len);
|
||||
ssize_t write_proc(int pid, uintptr_t remote_addr, const void *buf, size_t len);
|
||||
|
||||
ssize_t read_proc(int pid, uintptr_t *remote_addr, void *buf, size_t len);
|
||||
ssize_t read_proc(int pid, uintptr_t remote_addr, void *buf, size_t len);
|
||||
|
||||
bool get_regs(int pid, struct user_regs_struct ®s);
|
||||
|
||||
bool set_regs(int pid, struct user_regs_struct ®s);
|
||||
|
||||
std::string get_addr_mem_region(std::vector<MapInfo> &info, void *addr);
|
||||
std::string get_addr_mem_region(std::vector<MapInfo> &info, uintptr_t addr);
|
||||
|
||||
void *find_module_base(std::vector<MapInfo> &info, std::string_view suffix);
|
||||
|
||||
@@ -80,7 +80,7 @@ void *find_func_addr(
|
||||
|
||||
void align_stack(struct user_regs_struct ®s, long preserve = 0);
|
||||
|
||||
void *push_string(int pid, struct user_regs_struct ®s, const char *str);
|
||||
uintptr_t push_string(int pid, struct user_regs_struct ®s, const char *str);
|
||||
|
||||
uintptr_t remote_call(int pid, struct user_regs_struct ®s, uintptr_t func_addr, uintptr_t return_addr,
|
||||
std::vector<long> &args);
|
||||
|
||||
Reference in New Issue
Block a user