Update injector.cpp

This commit is contained in:
gggaa2152 2026-04-06 08:17:54 +08:00 committed by GitHub
parent 43522ffe83
commit 9c0ef289dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -11,11 +11,19 @@
#include <unistd.h>
#include <cstring>
#include <android/log.h>
#include <errno.h>
#include <elf.h> // 修复 NT_PRSTATUS 未定义问题
#include <linux/elf.h> // 备用包含
#define TAG "AndKitty_Injector"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
// 确保 NT_PRSTATUS 在某些 NDK 版本中被正确定义
#ifndef NT_PRSTATUS
#define NT_PRSTATUS 1
#endif
using namespace std;
// 获取目标进程 PID
@ -31,12 +39,14 @@ pid_t get_pid(const char* package_name) {
FILE* f = fopen(path, "r");
if (f) {
char cmdline[256];
fgets(cmdline, sizeof(cmdline), f);
fclose(f);
if (strncmp(cmdline, package_name, strlen(package_name)) == 0) {
closedir(dir);
return pid;
if (fgets(cmdline, sizeof(cmdline), f)) {
if (strncmp(cmdline, package_name, strlen(package_name)) == 0) {
fclose(f);
closedir(dir);
return pid;
}
}
fclose(f);
}
}
closedir(dir);
@ -53,7 +63,7 @@ uintptr_t get_module_base(pid_t pid, const char* module_name) {
uintptr_t base = 0;
while (fgets(line, sizeof(line), f)) {
if (strstr(line, module_name)) {
base = strtoull(line, NULL, 16);
base = (uintptr_t)strtoull(line, NULL, 16);
break;
}
}
@ -82,22 +92,29 @@ bool ptrace_write(pid_t pid, uintptr_t addr, void* buf, size_t len) {
// Ptrace 调用远程函数 (ARM64)
uint64_t ptrace_call(pid_t pid, uintptr_t func_addr, uint64_t* args, int nargs) {
struct user_pt_regs regs, old_regs;
struct iovec iov = {&regs, sizeof(struct user_pt_regs)};
ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
struct iovec iov;
iov.iov_base = &regs;
iov.iov_len = sizeof(struct user_pt_regs);
if (ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) < 0) return 0;
memcpy(&old_regs, &regs, sizeof(regs));
for (int i = 0; i < nargs && i < 8; i++) regs.regs[i] = args[i];
regs.regs[30] = 0; // LR 置零以便触发停止
regs.regs[30] = 0; // LR set to 0 to trigger crash/stop
regs.pc = func_addr;
iov.iov_base = &regs;
ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov);
if (ptrace(PTRACE_SETREGSET, pid, (void*)NT_PRSTATUS, &iov) < 0) return 0;
ptrace(PTRACE_CONT, pid, NULL, NULL);
waitpid(pid, NULL, WUNTRACED);
ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov);
uint64_t res = regs.regs[0];
ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &old_regs);
iov.iov_base = &old_regs;
ptrace(PTRACE_SETREGSET, pid, (void*)NT_PRSTATUS, &iov);
return res;
}
@ -110,54 +127,58 @@ int main(int argc, char** argv) {
const char* pkg = argv[1];
const char* so_path = argv[2];
LOGI("开始注入: %s -> %s", pkg, so_path);
LOGI("Starting injection: %s -> %s", pkg, so_path);
pid_t pid = get_pid(pkg);
if (pid < 0) {
LOGE("未找到进程 PID");
LOGE("Process PID not found for %s", pkg);
return -1;
}
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
LOGE("Ptrace Attach 失败: %s", strerror(errno));
LOGE("Ptrace Attach failed: %s", strerror(errno));
return -1;
}
waitpid(pid, NULL, WUNTRACED);
LOGI("成功附加到 PID: %d", pid);
LOGI("Attached to PID: %d", pid);
// 尝试从不同的库寻找 dlopen
uintptr_t remote_dlopen = get_remote_addr(pid, "libdl.so", (void*)dlopen);
if (!remote_dlopen) remote_dlopen = get_remote_addr(pid, "linker64", (void*)dlopen);
if (!remote_dlopen) {
LOGE("无法定位远程 dlopen 地址");
LOGE("Could not locate remote dlopen");
ptrace(PTRACE_DETACH, pid, NULL, NULL);
return -1;
}
LOGI("远程 dlopen 地址: %p", (void*)remote_dlopen);
LOGI("Remote dlopen: %p", (void*)remote_dlopen);
struct user_pt_regs regs;
struct iovec iov = {&regs, sizeof(struct user_pt_regs)};
ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
uintptr_t remote_str_addr = regs.sp - 1024; // 在栈下方写入路径
if (ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) < 0) {
LOGE("GetRegset failed");
ptrace(PTRACE_DETACH, pid, NULL, NULL);
return -1;
}
uintptr_t remote_str_addr = regs.sp - 1024;
if (!ptrace_write(pid, remote_str_addr, (void*)so_path, strlen(so_path) + 1)) {
LOGE("写入路径到远程内存失败");
LOGE("Write remote memory failed");
ptrace(PTRACE_DETACH, pid, NULL, NULL);
return -1;
}
uint64_t args[2] = { remote_str_addr, RTLD_NOW };
LOGI("正在执行远程 dlopen...");
LOGI("Calling remote dlopen...");
uint64_t handle = ptrace_call(pid, remote_dlopen, args, 2);
if (handle == 0) {
LOGE("注入失败: dlopen 返回 NULL (可能权限不足或路径错误)");
LOGE("Injection failed: dlopen returned NULL");
} else {
LOGI("注入成功! 句柄: %p", (void*)handle);
LOGI("Injection success! Handle: %p", (void*)handle);
}
ptrace(PTRACE_DETACH, pid, NULL, NULL);
LOGI("已分离进程.");
LOGI("Detached.");
return 0;
}