文章目录

  • 一、获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址
  • 二、从 /proc/pid/maps 文件中获取 指定 进程 中的 /system/lib/libc.so 动态库地址
  • 三、获取 本地进程 中的 /system/lib/libc.so 动态库的 mmap 函数地址
  • 四、获取 远程进程 中的 /system/lib/libc.so 动态库的 mmap 函数地址

一、获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址


获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址流程 :

① 获取 本地进程 /system/lib/libc.so 动态库 地址 ;

② 获取 远程进程 /system/lib/libc.so 动态库 地址 ;

③ 计算 本地进程 与 远程进程 的 /system/lib/libc.so 动态库 地址 偏移量 ;

④ 获取 本地进程 mmap 函数地址 ;

⑤ 根据 本地进程 mmap 函数地址 + 本地进程 与 远程进程 的 /system/lib/libc.so 动态库 地址 偏移量 , 计算出 远程进程 /system/lib/libc.so 动态库 的 mmap 函数地址 ;

二、从 /proc/pid/maps 文件中获取 指定 进程 中的 /system/lib/libc.so 动态库地址


查看 /proc/2223/maps 进程对应的内存信息 :

其中涉及到 /system/lib/libc.so 动态库的地址的行 :

b758c000-b758f000 r--p 000e6000 08:02 848        /system/lib/libc.so

首先 , 要获取到 maps 文件地址 ,

  • 获取本进程的 maps 文件地址 , 直接使用 "/proc/self/maps" 字符串作为地址 ;
  • 获取远程进程 maps 文件地址 , 需要 "/proc/%d/maps", pid 将 pid 拼接到 “/proc/%d/maps” 字符串中 ;
 char filename[32];  // maps 文件路径/* 获取 maps 文件路径 */if (pid < 0) {/* self process 本进程 */snprintf(filename, sizeof(filename), "/proc/self/maps");}else {/* 远程进程 */snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);}

然后 , 使用只读方式 , 打开文件 ;

 FILE* fp;   // 文件描述符/* 打开 maps 文件 */fp = fopen(filename, "r");

最后 , 解析文件中的内容 , 按照 b758c000-b758f000 r--p 000e6000 08:02 848 /system/lib/libc.so 格式解析即可 ;

  • 逐行遍历文件 , fgets(line, sizeof(line), fp) ;
  • 读取一行之后 , 查看该行是否包含 "/system/lib/libc.so" 字符串子串 , strstr(line, module_name) ;
  • 如果包含 , 则根据 - 字符 , 将其分割成字符串数组 , pch = strtok(line, "-") ;
  • 该数组的第一个字符串就是地址值对应的字符串 ,
  • 将字符串地址转为 int 类型地址 , 该地址就是 远程 目标进程 中的 /system/lib/libc.so 动态库地址 ; addr = strtoul(pch, NULL, 16)

解析文件代码如下 :

 if (fp != NULL) {/* 逐行遍历 maps 文件 */while (fgets(line, sizeof(line), fp)) {/* 下面是数据行示例 *//* b758c000-b758f000 r--p 000e6000 08:02 848        /system/lib/libc.so *//* 找到查找的 module_name 行 , 如果 module_name 是 line 的子串 , 返回 module_name 首次出现的地址 */if (strstr(line, module_name)) {/* 按照 - 字符 , 分割字符串 , 返回第一个字符串 */pch = strtok(line, "-");/* 将 "b758c000" 字符串转为 b758c000 整型 */addr = strtoul(pch, NULL, 16);if (addr == 0x8000)addr = 0;break;}}/* 关闭文件 */fclose(fp);}

从 /proc/pid/maps 文件中获取 指定 进程 中的 /system/lib/libc.so 动态库地址代码 :

/* 从 /proc/pid/maps 文件中获取 */
void* get_module_base(pid_t pid, const char* module_name)
{FILE* fp;long addr = 0;char* pch; // 字符串char filename[32];char line[1024];/* 获取 maps 文件路径 */if (pid < 0) {/* self process 本进程 */snprintf(filename, sizeof(filename), "/proc/self/maps");}else {/* 远程进程 */snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);}/* 打开 maps 文件 */fp = fopen(filename, "r");if (fp != NULL) {/* 逐行遍历 maps 文件 */while (fgets(line, sizeof(line), fp)) {/* 下面是数据行示例 *//* b758c000-b758f000 r--p 000e6000 08:02 848        /system/lib/libc.so *//* 找到查找的 module_name 行 , 如果 module_name 是 line 的子串 , 返回 module_name 首次出现的地址 */if (strstr(line, module_name)) {/* 按照 - 字符 , 分割字符串 , 返回第一个字符串 */pch = strtok(line, "-");/* 将 "b758c000" 字符串转为 b758c000 整型 */addr = strtoul(pch, NULL, 16);if (addr == 0x8000)addr = 0;break;}}/* 关闭文件 */fclose(fp);}/* 返回指定的 module_name 动态库地址 */return (void*)addr;
}

三、获取 本地进程 中的 /system/lib/libc.so 动态库的 mmap 函数地址


获取本地进程的函数地址 , 函数名就是函数地址 ; (void*)mmap 就是 mmap 函数对应的函数指针 ;

 /* 获取 目标进程中的 /system/lib/libc.so 动态库中的 mmap 函数地址 (void*)mmap 是本进程中 mmap 函数的地址 计算出 本进程 与 远程目标进程 libc.so 的偏移量 使用本进程的 mmap 函数地址 + 偏移量 , 就可以得到目标进程 mmap 函数地址*/mmap_addr = get_remote_addr(target_pid, libc_path, (void*)mmap);

四、获取 远程进程 中的 /system/lib/libc.so 动态库的 mmap 函数地址


分别调用 get_module_base 方法 , 获取本地进程 和 特定 PID 进程号对应的远程目标进程 的 /system/lib/libc.so 动态库 首地址 , 计算出这两个首地址之间的偏移量 (uint32_t)remote_handle - (uint32_t)local_handle ;

本进程的 mmap 函数的地址是已知的 , 直接使用 (void*)mmap 就可以获取 ;

使用 本进程的 mmap 函数地址 + 偏移量 , 就可以得到目标进程 mmap 函数地址 ;

char* ret_addr = (char*)((uint32_t)local_addr + (uint32_t)remote_handle - (uint32_t)local_handle)

完整代码示例 :

/* 获取 target_pid 进程的 module_name 动态库中的 local_addr 函数地址 */
void* get_remote_addr(pid_t target_pid, const char* module_name, void* local_addr)
{void* local_handle, * remote_handle;/* 获取本进程 module_name 动态库地址 */local_handle = get_module_base(-1, module_name);/* 获取远程目标进程 module_name 动态库地址 */remote_handle = get_module_base(target_pid, module_name);char* ret_addr = (char*)((uint32_t)local_addr + (uint32_t)remote_handle - (uint32_t)local_handle);LOGW("[+] get_remote_addr[%s]: local[%p], remote[%p], ret_addr[%p], local_addr[%p]\n", module_name, local_handle, remote_handle, ret_addr, local_addr);
#if defined(__i386__)if (!strcmp(module_name, libc_path)) {//ret_addr += 2;}
#endif  return ret_addr;
}

【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址 )相关推荐

  1. 【Android 逆向】Android 中常用的 so 动态库 ( /system/lib/libc.so 动态库 | libc++.so 动态库 | libstdc++.so 动态库 )

    文章目录 一.拷贝并分析 Android 中的 /system/lib/libc.so 动态库 二.拷贝并分析 Android 中的 /system/lib/libc++.so 动态库 三.拷贝并分析 ...

  2. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取注入的 libbridge.so 动态库中的 load 函数地址 并 通过 远程调用 执行该函数 )

    文章目录 一.dlsym 函数简介 二.获取 目标进程 linker 中的 dlsym 函数地址 三.远程调用 目标进程 linker 中的 dlsym 函数 获取 注入的 libbridge.so ...

  3. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 linker 中的 dlopen 函数地址 并 通过 远程调用 执行该函数 )

    文章目录 一.dlopen 函数简介 二.获取 目标进程 linker 中的 dlopen 函数地址 三.远程调用 目标进程 linker 中的 dlopen 函数 一.dlopen 函数简介 dlo ...

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

    文章目录 一.准备 mmap 函数的参数 二.mmap 函数远程调用 一.准备 mmap 函数的参数 上一篇博客 [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | 远程调 ...

  5. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 注入工具收尾操作 | 关闭注入的动态库 | 恢复寄存器 | 脱离远程调试附着 )

    文章目录 一.dlclose 函数简介 二.关闭注入的 libbridge.so 动态库 三.恢复寄存器 四.脱离远程调试附着 一.dlclose 函数简介 dlclose 函数的作用是 卸载一个 指 ...

  6. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 三 | 等待远程函数执行完毕 | 寄存器获取返回值 )

    文章目录 前言 一.等待远程进程 mmap 函数执行完毕 二.从寄存器中获取进程返回值 三.博客资源 前言 前置博客 : [Android 逆向]Android 进程注入工具开发 ( 注入代码分析 | ...

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

    文章目录 一.调试进程 ATTACH 附着目标进程 二.读取目标函数寄存器值并存档 1.主要操作流程 2.ptrace 函数 PTRACE_GETREGS 读取寄存器值 一.调试进程 ATTACH 附 ...

  8. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 注入工具的 main 函数分析 )

    文章目录 一.注入流程 二.注入工具的 main 函数分析 一.注入流程 开始分析 [Android 逆向]Android 进程注入工具开发 ( 编译注入工具 | 编译结果文件说明 | 注入过程说明 ...

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

    文章目录 一.mmap 简介 二.mmap 函数作用 一.mmap 简介 mmap 函数的作用是 将 文件 映射到 内存中 , 映射的单位必须是 PAGE_SIZE ; mmap 函数引入头文件 : ...

最新文章

  1. BS-XX-020基于SSM实现停车位租赁系统
  2. call of overloaded 'round(float)' is ambiguous
  3. 经典博文--各系列文章
  4. shell经典脚本或命令行
  5. 关于SparkStreaming的checkpoint的弊端
  6. 香港连续25年被评为全球最自由经济体
  7. C# 序列化与反序列化json
  8. java会被rust替代吗_Rust 未来会成为主流的编程语言吗?
  9. UI素材干货模板|网页“按钮”组件,教你要如何设计!
  10. javascript生成m位随机数
  11. Apple 官方文档翻译:NSURLSession
  12. 有序多分类Logistic回归(图文+数据集)【SPSS 079期】
  13. 468.验证IP地址
  14. 使用ASP.NET Core2.2创建WebApp
  15. 关于flymcu烧录stm32芯片超时的问题解决
  16. LinuxISO镜像挂载
  17. seata的部署与微服务集成(包含多集群异地容灾配置)
  18. python四边形转矩形_如何用PIL将矩形图像映射成四边形?
  19. flash基本操作二-库面板和元件创建
  20. 常用的软件(百度网盘分享:永久有效)

热门文章

  1. 网站如何接入支付宝(转)
  2. 吐槽一下现在的代码编辑器
  3. Android消息处理系统——Looper、Handler、Thread(转载)
  4. legend3---lavarel安装debugbar工具条
  5. Debian 安装docker
  6. webpack基础+webpack配置文件常用配置项介绍+webpack-dev-server
  7. [转]SupSite页面文件与模块关系说明
  8. Abaqus中施加移动车辆荷载(待整理)
  9. 图论数学:矩阵树定理
  10. HDU 3949 XOR 线性基