【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址 )
文章目錄
- 一、獲取 遠程 目標進程 中的 /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” 字符串中 ;
然后 , 使用只讀方式 , 打開文件 ;
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 函数地址 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 逆向】Android
- 下一篇: 【Android 逆向】Android