Update injector.cpp

This commit is contained in:
gggaa2152 2026-07-22 21:42:40 +08:00 committed by GitHub
parent 6c3b234eb8
commit d2078da9bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -16,13 +16,12 @@
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/ucontext.h>
#include <sys/mman.h>
#include <dirent.h>
#include <fcntl.h>
#include <vector>
#include <errno.h>
#include <dlfcn.h>
#include <cstdint>
#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, &regs);
@ -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;
}