From d2078da9bbd8f87a5fd9f56396dda707c4272863 Mon Sep 17 00:00:00 2001 From: gggaa2152 <60614405+gggaa2152@users.noreply.github.com> Date: Wed, 22 Jul 2026 21:42:40 +0800 Subject: [PATCH] Update injector.cpp --- injector.cpp | 113 +++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 58 deletions(-) diff --git a/injector.cpp b/injector.cpp index a12d77ca6..14a53dfa1 100644 --- a/injector.cpp +++ b/injector.cpp @@ -16,13 +16,12 @@ #include #include #include -#include #include #include #include -#include #include #include +#include #define GAME_PACKAGE "com.tencent.jkchess" #define SO_PATH "/data/1/libMyMenu.so" @@ -32,6 +31,7 @@ using u64 = uint64_t; using s64 = int64_t; +// 获取游戏进程PID pid_t get_target_pid() { DIR* dir = opendir("/proc"); if (!dir) return -1; @@ -54,6 +54,7 @@ pid_t get_target_pid() { return -1; } +// ptrace写入内存 bool pt_write(pid_t pid, u64 addr, const void* data, size_t len) { const u64* src = (const u64*)data; size_t full = len / 8; @@ -72,23 +73,7 @@ bool pt_write(pid_t pid, u64 addr, const void* data, size_t len) { return true; } -bool pt_read(pid_t pid, u64 addr, void* out, size_t len) { - u64* dst = (u64*)out; - size_t full = len / 8; - size_t rem = len % 8; - for (size_t i = 0; i < full; i++) { - if (ptrace(PTRACE_PEEKTEXT, pid, addr + i * 8, &dst[i]) == -1) - return false; - } - if (rem > 0) { - u64 last = 0; - if (ptrace(PTRACE_PEEKTEXT, pid, addr + full * 8, &last) == -1) - return false; - memcpy((char*)dst + full * 8, &last, rem); - } - return true; -} - +// 远程函数调用 u64 remote_call(pid_t pid, u64 func, u64 x0=0, u64 x1=0, u64 x2=0, u64 x3=0, u64 x4=0, u64 x5=0) { user_regs_struct regs; ptrace(PTRACE_GETREGS, pid, nullptr, ®s); @@ -107,14 +92,15 @@ u64 remote_call(pid_t pid, u64 func, u64 x0=0, u64 x1=0, u64 x2=0, u64 x3=0, u64 return regs.regs[0]; } -// 【修复点】正确扫描shturl.基地址 -u64 get_lib_base(pid_t pid) { - char buf[512], path[256]; +// ✅【重点修复】扫描 shturl. 基地址,不再使用错误字符串 +u64 get_libc_base(pid_t pid) { + char buf[1024], path[256]; snprintf(path, sizeof(path), "/proc/%d/maps", pid); FILE* f = fopen(path, "r"); if (!f) return 0; u64 base = 0; while (fgets(buf, sizeof(buf), f)) { + // 匹配系统标准libc if (strstr(buf, "shturl.")) { sscanf(buf, "%lx", &base); break; @@ -124,76 +110,87 @@ u64 get_lib_base(pid_t pid) { return base; } -u64 get_libc_sym(u64 lib_base, const char* sym) { - void* local_sym = dlsym(RTLD_DEFAULT, sym); - if (!local_sym) return 0; +// 根据libc基址解析符号地址 +u64 get_sym_addr(u64 lib_base, const char* sym_name) { + void* local_ptr = dlsym(RTLD_DEFAULT, sym_name); + if (!local_ptr) return 0; Dl_info info; - dladdr(local_sym, &info); - u64 off = (u64)local_sym - (u64)info.dli_fbase; - return lib_base + off; + dladdr(local_ptr, &info); + u64 offset = (u64)local_ptr - (u64)info.dli_fbase; + return lib_base + offset; } int main() { - printf("======== AArch64 Android Ptrace Injector ========\n"); - printf("Target SO: %s\n", SO_PATH); + printf("===== AArch64 Ptrace Injector (dlopen文件路径方案) =====\n"); + printf("Inject SO Path: %s\n", SO_PATH); system("su -c setenforce 0"); sleep(1); pid_t target_pid = get_target_pid(); if (target_pid <= 0) { - printf("Error: Game process not found, launch game first!\n"); + printf("错误:未找到游戏进程,请先打开游戏!\n"); return 1; } - printf("Target PID: %d\n", target_pid); + printf("目标进程 PID: %d\n", target_pid); + // Attach目标进程 if (ptrace(PTRACE_ATTACH, target_pid, nullptr, nullptr) == -1) { - perror("PTRACE_ATTACH failed, check root"); + perror("PTRACE_ATTACH 失败,请确认ROOT权限"); return 1; } waitpid(target_pid, nullptr, 0); - printf("Attached target process\n"); + printf("成功Attach进程\n"); - u64 libc_base = get_lib_base(target_pid); + // 获取libc基址 + u64 libc_base = get_libc_base(target_pid); if (libc_base == 0) { - printf("Failed get libc base address\n"); + printf("❌ Failed get libc base address\n"); + ptrace(PTRACE_DETACH, target_pid, nullptr, nullptr); + return 1; + } + printf("shturl. base: 0x%lx\n", libc_base); + + // 解析需要的libc函数 + u64 mmap_addr = get_sym_addr(libc_base, "mmap"); + u64 munmap_addr = get_sym_addr(libc_base, "munmap"); + u64 dlopen_addr = get_sym_addr(libc_base, "dlopen"); + + if (!mmap_addr || !munmap_addr || !dlopen_addr) { + printf("函数符号解析失败\n"); ptrace(PTRACE_DETACH, target_pid, nullptr, nullptr); return 1; } - u64 mmap_sym = get_libc_sym(libc_base, "mmap"); - u64 munmap_sym = get_libc_sym(libc_base, "munmap"); - u64 dlopen_sym = get_libc_sym(libc_base, "dlopen"); - if (!mmap_sym || !munmap_sym || !dlopen_sym) { - printf("Resolve libc function failed\n"); - ptrace(PTRACE_DETACH, target_pid, nullptr, nullptr); - return 1; - } + // 分配一小块内存存放SO路径字符串(仅4KB内,规避大块mmap拦截) + const char* so_file_path = SO_PATH; + size_t str_len = strlen(so_file_path) + 1; + size_t alloc_size = PAGE_ALIGN(str_len); - const char* path_str = SO_PATH; - size_t str_len = strlen(path_str) + 1; - size_t str_alloc = PAGE_ALIGN(str_len); - - u64 str_ptr = remote_call(target_pid, mmap_sym, - 0, str_alloc, PROT_READ | PROT_WRITE, + u64 str_buf = remote_call(target_pid, mmap_addr, + 0, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, 0, 0); - if (str_ptr == 0 || str_ptr == ULLONG_MAX) { - printf("Remote mmap allocate failed\n"); + if (str_buf == 0 || str_buf == ULLONG_MAX) { + printf("❌ Remote mmap allocate failed(游戏拦截mmap调用)\n"); ptrace(PTRACE_DETACH, target_pid, nullptr, nullptr); return 1; } - pt_write(target_pid, str_ptr, path_str, str_len); - u64 handle = remote_call(target_pid, dlopen_sym, str_ptr, RTLD_NOW | RTLD_GLOBAL); + // 把路径字符串写入游戏进程内存 + pt_write(target_pid, str_buf, so_file_path, str_len); - if (handle != 0) { - printf("✅ Inject Success! Handle: 0x%lx\n", handle); + // 远程调用 dlopen 加载本地so + u64 so_handle = remote_call(target_pid, dlopen_addr, str_buf, RTLD_NOW | RTLD_GLOBAL); + + if (so_handle != 0) { + printf("✅ 注入成功! SO句柄:0x%lx\n", so_handle); } else { - printf("❌ Inject Failed, dlopen returned NULL\n"); + printf("❌ dlopen返回NULL,检查SO文件权限、路径是否正确\n"); } - remote_call(target_pid, munmap_sym, str_ptr, str_alloc); + // 释放临时内存、解除附着 + remote_call(target_pid, munmap_addr, str_buf, alloc_size); ptrace(PTRACE_DETACH, target_pid, nullptr, nullptr); return 0; }