int inject_remote_process(pid_t pid, char *LibPath, char *FunctionName, long *FuncParameter, long NumParameter){int iRet = -1;struct pt_regs CurrentRegs, OriginalRegs; // CurrentRegs表示远程进程中当前的寄存器值,OriginalRegs存储注入前的寄存器值,方便恢复void *mmap_addr, *dlopen_addr, *dlsym_addr, *dlclose_addr, *dlerror_addr; // 远程进程中需要调用函数的地址void *RemoteMapMemoryAddr, *RemoteModuleAddr, *RemoteModuleFuncAddr; // RemoteMapMemoryAddr为远程进程空间中映射的内存基址,RemoteModuleAddr为远程注入的so模块加载基址,RemoteModuleFuncAddr为注入模块中需要调用的函数地址long parameters[6];// Attach远程进程if (ptrace_attach(pid) == -1) return iRet;
// 获取远程进程的寄存器值if (ptrace_getregs(pid, &CurrentRegs) == -1){ ptrace_detach(pid); return iRet;}
// 保存远程进程空间中当前的上下文寄存器环境memcpy(&OriginalRegs, &CurrentRegs, sizeof(CurrentRegs));
// 获取mmap函数在远程进程中的地址mmap_addr = GetRemoteFuncAddr(pid, libc_path, (void *)mmap);LOGD("mmap RemoteFuncAddr:0x%lx", (long)mmap_addr);
// 设置mmap的参数// void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offsize);parameters[0] = 0; // 设置为NULL表示让系统自动选择分配内存的地址 parameters[1] = 0x1000; // 映射内存的大小 parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // 表示映射内存区域可读可写可执行 parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // 建立匿名映射 parameters[4] = 0; // 若需要映射文件到内存中,则为文件的fd parameters[5] = 0; //文件映射偏移量
// 调用远程进程的mmap函数,建立远程进程的内存映射if (ptrace_call(pid, (long)mmap_addr, parameters, 6, &CurrentRegs) == -1){ LOGD("Call Remote mmap Func Failed"); ptrace_detach(pid); return iRet;}
// 获取mmap函数执行后的返回值,也就是内存映射的起始地址RemoteMapMemoryAddr = (void *)ptrace_getret(&CurrentRegs);LOGD("Remote Process Map Memory Addr:0x%lx", (long)RemoteMapMemoryAddr);
// 分别获取dlopen、dlsym、dlclose等函数的地址dlopen_addr = GetRemoteFuncAddr(pid, linker_path, (void *)dlopen);dlsym_addr = GetRemoteFuncAddr(pid, linker_path, (void *)dlsym);dlclose_addr = GetRemoteFuncAddr(pid, linker_path, (void *)dlclose);dlerror_addr = GetRemoteFuncAddr(pid, linker_path, (void *)dlerror);
// 将要加载的so库路径写入到远程进程内存空间中if (ptrace_writedata(pid, RemoteMapMemoryAddr, LibPath, strlen(LibPath) + 1) == -1){ ptrace_detach(pid); return iRet;}
// 设置dlopen的参数,返回值为模块加载的地址// void *dlopen(const char *filename, int flag);parameters[0] = (long)RemoteMapMemoryAddr;parameters[1] = RTLD_NOW| RTLD_GLOBAL;
if (ptrace_call(pid, (long)dlopen_addr, parameters, 2, &CurrentRegs) == -1){ ptrace_detach(pid); return iRet;}
// RemoteModuleAddr为远程进程加载注入模块的地址RemoteModuleAddr = (void *)ptrace_getret(&CurrentRegs);
if ((long)RemoteModuleAddr == 0x0) // dlopen 错误{ LOGD("dlopen error"); if (ptrace_call(pid, (long)dlerror_addr, parameters, 0, &CurrentRegs) == -1) { LOGD("Call Remote dlerror Func Failed"); ptrace_detach(pid); return iRet; } char *Error = (void *)ptrace_getret(&CurrentRegs); char LocalErrorInfo[1024] = {0}; ptrace_readdata(pid, Error, LocalErrorInfo, 1024); ptrace_detach(pid); return iRet;}
// 将so库中需要调用的函数名称写入到远程进程内存空间中if (ptrace_writedata(pid, RemoteMapMemoryAddr + strlen(LibPath) + 2, FunctionName, strlen(FunctionName) + 1) == -1){ ptrace_detach(pid); return iRet;}
// 设置dlsym的参数,返回值为远程进程内函数的地址// void *dlsym(void *handle, const char *symbol);parameters[0] = (long)RemoteModuleAddr;parameters[1] = (long)(RemoteMapMemoryAddr + strlen(LibPath) + 2);
if (ptrace_call(pid, (long)dlsym_addr, parameters, 2, &CurrentRegs) == -1){ LOGD("Call Remote dlsym Func Failed"); ptrace_detach(pid); return iRet;}
// RemoteModuleFuncAddr为远程进程空间内获取的函数地址RemoteModuleFuncAddr = (void *)ptrace_getret(&CurrentRegs);
if (ptrace_call(pid, (long)RemoteModuleFuncAddr, FuncParameter, NumParameter, &CurrentRegs) == -1){ LOGD("Call Remote injected Func Failed"); ptrace_detach(pid); return iRet;}
if (ptrace_setregs(pid, &OriginalRegs) == -1){ LOGD("Recover reges failed"); ptrace_detach(pid); return iRet; }
ptrace_getregs(pid, &CurrentRegs);if (memcmp(&OriginalRegs, &CurrentRegs, sizeof(CurrentRegs)) != 0){ LOGD("Set Regs Error");}
//剥离if (ptrace_detach(pid) == -1){ LOGD("ptrace detach failed"); return iRet;}
return 0;
评论