Workflow config file is invalid. Please check your config file: yaml: line 94: mapping values are not allowed in this context
2026-04-06 02:56:18 +08:00

113 lines
3.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <dirent.h>
#include <dlfcn.h>
#include <sys/uio.h>
#include <elf.h>
// --- 手动补全 NDK 缺失的定义 ---
#ifndef NT_PRSTATUS
#define NT_PRSTATUS 1
#endif
#ifndef RTLD_DEFAULT
#define RTLD_DEFAULT ((void *) 0LL)
#endif
// 目标包名 (王者荣耀)
const char* TARGET_PKG = "com.tencent.tmgp.sgame";
// 注意:注入器会去这个路径找 SO,确保你 push 到了这里
const char* LIB_PATH = "/data/local/tmp/libJKMenu.so";
pid_t find_pid_by_name(const char* package_name) {
DIR* dir = opendir("/proc");
if (!dir) return -1;
struct dirent* entry;
while ((entry = readdir(dir))) {
pid_t pid = atoi(entry->d_name);
if (pid <= 0) continue;
char path[256], cmd[256];
snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
FILE* f = fopen(path, "r");
if (f) {
if (fgets(cmd, sizeof(cmd), f) && strstr(cmd, package_name)) {
fclose(f); closedir(dir); return pid;
}
fclose(f);
}
}
closedir(dir); return -1;
}
int main() {
pid_t pid = find_pid_by_name(TARGET_PKG);
if (pid == -1) {
printf("[-] Target process %s not found!\n", TARGET_PKG);
return 1;
}
// 1. 附加到进程
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
perror("[-] Attach failed");
return 1;
}
waitpid(pid, NULL, WUNTRACED);
// 2. 获取寄存器 (ARM64)
struct user_pt_regs regs;
struct iovec iov;
iov.iov_base = &regs;
iov.iov_len = sizeof(regs);
// 使用宏定义的 NT_PRSTATUS
if (ptrace(PTRACE_GETREGSET, pid, (void*)(uintptr_t)NT_PRSTATUS, &iov) < 0) {
perror("[-] PTRACE_GETREGSET failed");
ptrace(PTRACE_DETACH, pid, NULL, NULL);
return 1;
}
// 3. 定位远程 dlopen (在 Android linker64 中)
// 强制使用 __loader_dlopen,这是 Android 7+ 的标准
uintptr_t remote_dlopen = (uintptr_t)dlsym(RTLD_DEFAULT, "__loader_dlopen");
if (!remote_dlopen) {
printf("[-] Could not find __loader_dlopen. Trying dlopen...\n");
remote_dlopen = (uintptr_t)dlsym(RTLD_DEFAULT, "dlopen");
}
if (!remote_dlopen) {
printf("[-] Failed to locate dlopen symbols.\n");
ptrace(PTRACE_DETACH, pid, NULL, NULL);
return 1;
}
// 4. 准备调用:将 SO 路径写入远程栈
uintptr_t sp = (regs.sp - 512) & ~0xF; // 栈对齐
size_t len = strlen(LIB_PATH) + 1;
for (size_t i = 0; i < len; i += 8) {
long data = 0;
memcpy(&data, LIB_PATH + i, (len - i) < 8 ? (len - i) : 8);
ptrace(PTRACE_POKETEXT, pid, sp + i, (void*)data);
}
// 5. 设置寄存器执行 dlopen(path, RTLD_NOW)
regs.regs[0] = sp; // x0: so_path
regs.regs[1] = 2; // x1: RTLD_NOW
regs.regs[30] = 0; // LR: 归零,调用完会 SIGSEGV 停止,方便我们 detach
regs.pc = remote_dlopen;
ptrace(PTRACE_SETREGSET, pid, (void*)(uintptr_t)NT_PRSTATUS, &iov);
// 6. 恢复并分离
ptrace(PTRACE_DETACH, pid, NULL, NULL);
printf("[+] Successfully sent injection request to PID %d\n", pid);
printf("[+] Make sure libJKMenu.so is in /data/local/tmp/\n");
return 0;
}