From 675febfd14f7bcbb2fcb62964bcbd6c4cc6706c1 Mon Sep 17 00:00:00 2001 From: 5ec1cff Date: Fri, 5 Jan 2024 13:41:40 +0800 Subject: [PATCH] refine code --- loader/src/ptracer/monitor.cpp | 8 +++--- loader/src/ptracer/ptracer.cpp | 46 ++++++++++++++++++---------------- loader/src/ptracer/utils.cpp | 42 +++++++++++++++---------------- loader/src/ptracer/utils.hpp | 8 +++--- 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/loader/src/ptracer/monitor.cpp b/loader/src/ptracer/monitor.cpp index cb34247..eee9b74 100644 --- a/loader/src/ptracer/monitor.cpp +++ b/loader/src/ptracer/monitor.cpp @@ -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"); diff --git a/loader/src/ptracer/ptracer.cpp b/loader/src/ptracer/ptracer.cpp index 6331f0c..7ee54b9 100644 --- a/loader/src/ptracer/ptracer.cpp +++ b/loader/src/ptracer/ptracer.cpp @@ -14,6 +14,8 @@ #include #include #include +#include + #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(regs.REG_SP); - LOGD("kernel argument %p %s", arg, get_addr_mem_region(map, arg).c_str()); + auto arg = static_cast(regs.REG_SP); + LOGV("kernel argument %" PRIxPTR " %s", arg, get_addr_mem_region(map, arg).c_str()); int argc; auto argv = reinterpret_cast(reinterpret_cast(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(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(buf.a_un.a_val); - addr_of_entry_addr = reinterpret_cast(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(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; } diff --git a/loader/src/ptracer/utils.cpp b/loader/src/ptracer/utils.cpp index fdbc2ea..0706df3 100644 --- a/loader/src/ptracer/utils.cpp +++ b/loader/src/ptracer/utils.cpp @@ -102,8 +102,8 @@ std::vector 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(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(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 &info, void *addr) { +std::string get_addr_mem_region(std::vector &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(regs.REG_SP); + auto addr = static_cast(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 &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(regs.REG_IP) != return_addr) { LOGE("wrong return addr %p", (void *) regs.REG_IP); return 0; } diff --git a/loader/src/ptracer/utils.hpp b/loader/src/ptracer/utils.hpp index 14f9109..8ece432 100644 --- a/loader/src/ptracer/utils.hpp +++ b/loader/src/ptracer/utils.hpp @@ -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 &info, void *addr); +std::string get_addr_mem_region(std::vector &info, uintptr_t addr); void *find_module_base(std::vector &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 &args);