refine code

This commit is contained in:
5ec1cff
2024-01-05 13:41:40 +08:00
parent ad32c4efb0
commit 675febfd14
4 changed files with 54 additions and 50 deletions

View File

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

View File

@@ -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, &regs, 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;
}

View File

@@ -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 &regs) {
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 &regs, long preserve) {
regs.REG_SP = (regs.REG_SP - preserve) & ~0xf;
}
void *push_string(int pid, struct user_regs_struct &regs, const char *str) {
uintptr_t push_string(int pid, struct user_regs_struct &regs, 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 &regs, 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 &regs, 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 &regs, 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 &regs, 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;
}

View File

@@ -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 &regs);
bool set_regs(int pid, struct user_regs_struct &regs);
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 &regs, long preserve = 0);
void *push_string(int pid, struct user_regs_struct &regs, const char *str);
uintptr_t push_string(int pid, struct user_regs_struct &regs, const char *str);
uintptr_t remote_call(int pid, struct user_regs_struct &regs, uintptr_t func_addr, uintptr_t return_addr,
std::vector<long> &args);