700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标

【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标

时间:2018-07-21 23:00:18

相关推荐

【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标

文章目录

一、获取 远程 目标进程 中的 /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 函数地址 )

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。