【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
公网NAT网关,每月750个小时 15CU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )

文章目录

一、准备 mmap 函数的参数

二、mmap 函数远程调用





一、准备 mmap 函数的参数


上一篇博客 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 一 | mmap 函数简介 ) 中介绍了 mmap 函数 ;


mmap 函数的函数原型如下 :


<sys/mman.h>
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);
int munmap(void* start,size_t length);


mmap 函数参数含义 :


void* start : 如果为 0 就是让系统自动分配 , 如果不为 0 , 则由用户指定分配的地址 ;

size_t length : 申请分配内存的大小 ;

int prot : 内存保护标志 , 如 PROT_READ | PROT_WRITE | PROT_EXEC , 表示 可读 | 可写 | 可执行 ;

int flags : 映射对象类型标志位标志位 , 如 MAP_ANONYMOUS | MAP_PRIVATE , 表示 匿名 | 私有 ;

int fd : 文件描述符 ; 没有设置为 0 ;

off_t offset : 被映射对象的起点偏移量 , 一般设置 0 ;


将 mmap 的参数放到 parameters 数组中 , 之后要将该地址传递给远程进程的 ESP 寄存器 , 用于指定


long parameters[10];
  /* 下面是远程调用 mmap 函数分配栈内存信息 */
  /* call mmap 调用 mmap 函数传入的参数 */
  parameters[0] = 0;  // addr  地址让系统分配 , 也可以指定内存地址
  parameters[1] = 0x4000; // size 分配的内存大小 0x4000 字节 , 也就是 16KB ,  mmap 函数的参数胡
  parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC;  // prot  可读 | 可写 | 可执行 
  parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags  匿名 | 私有 
  parameters[4] = 0; //fd  文件描述符 
  parameters[5] = 0; //offset  偏移量






二、mmap 函数远程调用


由于远程调用涉及到寄存器的操作 , 因此 arm 架构 与 x86 架构的 远程调用是不同的 , 本次开发的是 x86 架构下的远程调用 ;



首先 , 将 mmap 函数执行的参数 , 写出到远程进程的内存中 , 调用 ptrace_writedata 方法 , 写出内存数据 ;


/* 设置 ESP 栈指针寄存器 */
  regs->esp -= (num_params) * sizeof(long);
  /* 将 long* params 参数写出到 pid 对应的远程进程中 , 然后将写出后数据的首地址 , 
    设置到 pid_t pid 进程号对应的远程进程的 ESP 寄存器中 , 
    设置的数据长度 4 字节 */
  ptrace_writedata(pid, (uint8_t*)(void*)regs->esp, (uint8_t*)params, (num_params) * sizeof(long));


此外还要在栈中设置一个 0 地址 , 为了保证远程进程执行完毕后 , 自动访问 0 地址 , 导致崩溃 , 这样调试程序就可以收回控制权 ; 参考 【Android 逆向】Android 进程注入工具开发 ( EIP 寄存器指向 dlopen 函数 | ESP 寄存器指向栈内存 | 调试程序收回目标进程控制权 ) 博客 ;


/* 设置一个 0 地址 */
  long tmp_addr = 0x00;
  /* 设置 0 地址的作用是 保证 远程进程 访问该 0 地址 导致崩溃 , 调试工具收回进程控制权 */
  regs->esp -= sizeof(long);
  ptrace_writedata(pid, (uint8_t*)(regs->esp), (uint8_t*)&tmp_addr, sizeof(tmp_addr));


然后 , 设置 远程进程 的 EIP 寄存器 , 指定执行哪个函数 , 这个 函数地址 是在 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址 ) 博客中获取的 mmap 函数地址 ;


/* 设置 EIP 寄存器值 , 存储 CPU 下一条将要执行的指令 */
  regs->eip = addr;
  /* 设置 pid 远程进程的寄存器值 */
  if (ptrace_setregs(pid, regs) == -1
  || ptrace_continue(pid) == -1) {
  printf("error\n");
  return -1;
  }


最后 , 调用 ptrace_continue 方法 , 执行该 mmap 函数 ;


ptrace_continue(pid)



mmap 函数远程调用 完整代码 :


#elif defined(__i386__)  
long ptrace_call(pid_t pid, uint32_t addr, long* params, uint32_t num_params, struct user_regs_struct* regs)
{
  /* 参数说明 :  */
  if (num_params > 0 && (params != NULL)) {
  /* 设置 ESP 栈指针寄存器 */
  regs->esp -= (num_params) * sizeof(long);
  /* 将 long* params 参数写出到 pid 对应的远程进程中 , 然后将写出后数据的首地址 , 
    设置到 pid_t pid 进程号对应的远程进程的 ESP 寄存器中 , 
    设置的数据长度 4 字节 */
  ptrace_writedata(pid, (uint8_t*)(void*)regs->esp, (uint8_t*)params, (num_params) * sizeof(long));
  }
  /* 设置一个 0 地址 */
  long tmp_addr = 0x00;
  /* 设置 0 地址的作用是 保证 远程进程 访问该 0 地址 导致崩溃 , 调试工具收回进程控制权 */
  regs->esp -= sizeof(long);
  ptrace_writedata(pid, (uint8_t*)(regs->esp), (uint8_t*)&tmp_addr, sizeof(tmp_addr));
  /* 设置 EIP 寄存器值 , 存储 CPU 下一条将要执行的指令 */
  regs->eip = addr;
  /* 设置 pid 远程进程的寄存器值 */
  if (ptrace_setregs(pid, regs) == -1
  || ptrace_continue(pid) == -1) {
  printf("error\n");
  return -1;
  }
  /* 等待远程调用执行完毕 */
  int stat = 0;
  waitpid(pid, &stat, WUNTRACED);
  while (stat != 0xb7f) {
  if (ptrace_continue(pid) == -1) {
    printf("error\n");
    return -1;
  }
  waitpid(pid, &stat, WUNTRACED);
  }
  return 0;
}



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
高可用应用架构
欢迎来到“高可用应用架构”课程,本课程是“弹性计算Clouder系列认证“中的阶段四课程。本课程重点向您阐述了云服务器ECS的高可用部署方案,包含了弹性公网IP和负载均衡的概念及操作,通过本课程的学习您将了解在平时工作中,如何利用负载均衡和多台云服务器组建高可用应用架构,并通过弹性公网IP的方式对外提供稳定的互联网接入,使得您的网站更加稳定的同时可以接受更多人访问,掌握在阿里云上构建企业级大流量网站场景的方法。 学习完本课程后,您将能够: 理解高可用架构的含义并掌握基本实现方法 理解弹性公网IP的概念、功能以及应用场景 理解负载均衡的概念、功能以及应用场景 掌握网站高并发时如何处理的基本思路 完成多台Web服务器的负载均衡,从而实现高可用、高并发流量架构
目录
相关文章
|
25天前
|
Java Shell Linux
从 am start 的 --user 参数说到 Android 多用户
am start 命令有时并不会乖乖如我们所愿,这时候我们需要知对策并知其所以然。
41 16
|
3月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
58 1
|
4月前
|
Java Android开发 iOS开发
探索安卓与iOS开发的差异性:平台、工具和用户体验的对比分析
【7月更文挑战第30天】在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据着不可忽视的地位。本文将深入探讨这两大平台在开发环境、工具选择以及最终用户体验上的根本差异,并分析这些差异如何影响开发者的策略和用户的偏好。通过比较安卓的开放性与iOS的封闭性,我们将揭示不同平台下的开发哲学及其对生态系统的影响。
45 4
|
4月前
|
开发工具 Android开发 数据安全/隐私保护
探索iOS与安卓应用开发的异同:技术、工具和市场趋势
在移动操作系统的广阔舞台上,iOS和安卓两大主角各自演绎着怎样的精彩?本文将深入剖析这两大平台在应用开发过程中的技术差异、开发工具的选择以及面对的市场环境。通过数据支撑和案例分析,我们将一窥这两个系统如何影响开发者的决策,并探讨它们未来的发展方向。
|
3月前
|
API 调度 Android开发
Android经典实战之处理后台任务的2个工具
本文介绍Android后台任务管理,涵盖WorkManager与JobScheduler的使用方法及区别。WorkManager属Jetpack库,确保任务可靠执行,支持延迟与条件依赖。JobScheduler则针对特定条件下的任务调度,如网络类型。两者各有优势,WorkManager适用于多数场景。
48 0
|
5月前
|
监控 Linux 应用服务中间件
探索Linux中的`ps`命令:进程监控与分析的利器
探索Linux中的`ps`命令:进程监控与分析的利器
127 13
|
4月前
|
运维 关系型数据库 MySQL
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
|
4月前
|
弹性计算 Linux 区块链
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
171 4
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
|
3月前
|
算法 Linux 调度
探索进程调度:Linux内核中的完全公平调度器
【8月更文挑战第2天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。本文将深入探讨Linux内核中的完全公平调度器(Completely Fair Scheduler, CFS),一个旨在提供公平时间分配给所有进程的调度器。我们将通过代码示例,理解CFS如何管理运行队列、选择下一个运行进程以及如何对实时负载进行响应。文章将揭示CFS的设计哲学,并展示其如何在现代多任务计算环境中实现高效的资源分配。
|
4月前
|
存储 缓存 安全
【Linux】冯诺依曼体系结构与操作系统及其进程
【Linux】冯诺依曼体系结构与操作系统及其进程
171 1

相关实验场景

更多
下一篇
无影云桌面