【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 调试进程 ATTACH 附着目标进程 | 读取目标函数寄存器值并存档 )

简介: 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 调试进程 ATTACH 附着目标进程 | 读取目标函数寄存器值并存档 )

文章目录

一、调试进程 ATTACH 附着目标进程

二、读取目标函数寄存器值并存档

1、主要操作流程

2、ptrace 函数 PTRACE_GETREGS 读取寄存器值





一、调试进程 ATTACH 附着目标进程


在 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 注入工具的 main 函数分析 ) 博客中 , 在 main 函数中获取了 进程号 PID , 下面开始将 SO 动态库注入该 PID 进程号对应的目标进程 ;


ptrace 函数调用的前提是 , 当前应用必须有 root 权限 , 否则调用会失败 ;


首先 , 调用


ptrace(PTRACE_ATTACH, pid, NULL, 0)


函数附着目标进程 , 获取目标进程的控制权 , 传入 PTRACE_ATTACH 参数 ;


具体的 ptrace 函数族的参数 , 参考 【Android 逆向】ptrace 函数 ( ptrace 函数族 | 进程附着 | 进程脱离 | 进程数据读写权限 | 进程对应的主线程寄存器读写 | 单步调试 |ptrace 函数族状态转换 ) 博客 ;


之后 , 需要 阻塞等待 被调试 的 目标进程返回 , 如果目标进程状态变为 WUNTRACED 被调试状态 , 就可以执行下一步的操作 ;


int status = 0;
  /* 等待关联进程结果返回 , 目标进程状态变为 WUNTRACED */
  waitpid(pid, &status, WUNTRACED);



附着目标进程完整代码 :


/* 附着目标进程 */
int ptrace_attach(pid_t pid)
{
  /* attach 关联 要调试的 目标进程 */
  if (ptrace(PTRACE_ATTACH, pid, NULL, 0) < 0) {
  perror("ptrace_attach");
  return -1;
  }
  int status = 0;
  /* 等待关联进程结果返回 , 目标进程状态变为 WUNTRACED */
  waitpid(pid, &status, WUNTRACED);
  return 0;
}





二、读取目标函数寄存器值并存档



1、主要操作流程


声明两个结构体 , 分别用于寄存器值操作 和 存档 , 存档的结构体一定不要写入数据 , 之后恢复寄存器值时需要用到 ;


/* regs 结构体 用于存储寄存器值
    original_regs 结构体 用于存储寄存器值存档 */
  struct pt_regs regs, original_regs;


之后 , 调用 ptrace_getregs 函数 , 读取目标进程的寄存器值 ;


/* 获取寄存器值 */
  if (ptrace_getregs(target_pid, &regs) == -1)
  goto exit;


最后 , 将寄存器的值存档 ,


/* save original registers 寄存器值存档 */
  memcpy(&original_regs, &regs, sizeof(regs));


寄存器读取存档代码示例 :


/* regs 结构体 用于存储寄存器值
    original_regs 结构体 用于存储寄存器值存档 */
  struct pt_regs regs, original_regs;
  /* 获取寄存器值 */
  if (ptrace_getregs(target_pid, &regs) == -1)
  goto exit;
  /* save original registers 寄存器值存档 */
  memcpy(&original_regs, &regs, sizeof(regs));



2、ptrace 函数 PTRACE_GETREGS 读取寄存器值


在 ptrace_getregs 函数中 , 调用


ptrace(PTRACE_GETREGS, pid, NULL, regs)


方法 , 获取目标进程的寄存器数据 , 传入 PTRACE_GETREGS 参数 ;


具体的 ptrace 函数族的参数 , 参考 【Android 逆向】ptrace 函数 ( ptrace 函数族 | 进程附着 | 进程脱离 | 进程数据读写权限 | 进程对应的主线程寄存器读写 | 单步调试 |ptrace 函数族状态转换 ) 博客 ;


/* 获取寄存器值 */
int ptrace_getregs(pid_t pid, struct pt_regs* regs)
{
  if (ptrace(PTRACE_GETREGS, pid, NULL, regs) < 0) {
  perror("ptrace_getregs: Can not get register values");
  return -1;
  }
  return 0;
}


目录
相关文章
|
Arthas 测试技术
这个错误提示表明Arthas无法打开目标进程的socket文
【1月更文挑战第11天】【1月更文挑战第55篇】这个错误提示表明Arthas无法打开目标进程的socket文
1489 4
|
Android开发
KernelSU基于内核的 SU。它通过自定义内核,直接在内核中赋予目标进程 root 权限。
KernelSU基于内核的 SU。它通过自定义内核,直接在内核中赋予目标进程 root 权限。
4423 0
|
10月前
|
运维 JavaScript jenkins
鸿蒙5.0版开发:分析CppCrash(进程崩溃)
在HarmonyOS 5.0中,CppCrash指C/C++运行时崩溃,常见原因包括空指针、数组越界等。系统提供基于posix信号机制的异常检测能力,生成详细日志辅助定位。本文详解CppCrash分析方法,涵盖异常检测、问题定位思路及案例分析。
338 4
|
10月前
|
运维 监控 JavaScript
鸿蒙next版开发:分析JS Crash(进程崩溃)
在HarmonyOS 5.0中,JS Crash指未处理的JavaScript异常导致应用意外退出。本文详细介绍如何分析JS Crash,包括异常捕获、日志分析和典型案例,帮助开发者定位问题、修复错误,提升应用稳定性。通过DevEco Studio收集日志,结合HiChecker工具,有效解决JS Crash问题。
375 4
|
Java 运维
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
143 2
|
SQL 自然语言处理 网络协议
【Linux开发实战指南】基于TCP、进程数据结构与SQL数据库:构建在线云词典系统(含注册、登录、查询、历史记录管理功能及源码分享)
TCP(Transmission Control Protocol)连接是互联网上最常用的一种面向连接、可靠的、基于字节流的传输层通信协议。建立TCP连接需要经过著名的“三次握手”过程: 1. SYN(同步序列编号):客户端发送一个SYN包给服务器,并进入SYN_SEND状态,等待服务器确认。 2. SYN-ACK:服务器收到SYN包后,回应一个SYN-ACK(SYN+ACKnowledgment)包,告诉客户端其接收到了请求,并同意建立连接,此时服务器进入SYN_RECV状态。 3. ACK(确认字符):客户端收到服务器的SYN-ACK包后,发送一个ACK包给服务器,确认收到了服务器的确
285 1
|
JavaScript 开发工具
Electron 开发过程中主进程的无法看到 console.log 输出怎么办
Electron 开发过程中主进程的无法看到 console.log 输出怎么办
|
机器学习/深度学习 数据可视化 搜索推荐
低代码开发是一种能够加速软件研发进程的高效开发方法
【8月更文挑战第4天】低代码开发是一种能够加速软件研发进程的高效开发方法
132 0
|
NoSQL Linux Redis
c++开发redis module问题之避免在fork后子进程中发生死锁,如何解决
c++开发redis module问题之避免在fork后子进程中发生死锁,如何解决
|
Java 调度 开发者
构建高效微服务架构:后端开发的新趋势深入理解操作系统之进程调度策略
【4月更文挑战第30天】 随着企业数字化转型的不断深入,传统的单体应用逐渐不能满足快速迭代和灵活部署的需求。微服务架构以其高度模块化、独立部署和易于扩展的特性,成为现代后端开发的重要趋势。本文将探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术选型以及可能面临的挑战。