文章目录
一、dlsym 函数简介
二、获取 目标进程 linker 中的 dlsym 函数地址
三、远程调用 目标进程 linker 中的 dlsym 函数 获取 注入的 libbridge.so 动态库中的 load 函数地址
四、远程调用 目标进程 中的 libbridge.so 动态库中的 load 函数
一、dlsym 函数简介
dlsym 是 Dynamic Library Symbol 的缩写 , 该函数的作用是 根据 动态链接库 句柄 和 符号 , 返回对应 符号的地址 , 这个符号可以是方法名 , 也可以是变量名 ;
包含头文件 :
#include<dlfcn.h>
函数原型 :
void* dlsym(void* handle, constchar* symbol)
参数说明 :
① void* handle : dlopen 打开 动态链接库 的返回值;
② constchar* symbol : 函数名称 / 全局变量名称 ;
void* 返回值 : 返回对应 函数 / 变量 地址 ;
二、获取 目标进程 linker 中的 dlsym 函数地址
获取 某个动态库 / 可执行文件 中的某个方法的地址 , 参考 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址 ) 博客 ;
获取 远程 目标进程 中的 动态库中的 函数地址流程 :
① 获取 本地进程 动态库 地址 ;
② 获取 远程进程 动态库 地址 ;
③ 计算 本地进程 与 远程进程 的 动态库 地址 偏移量 ;
④ 获取 本地进程 函数地址 ;
⑤ 根据 本地进程 函数地址 + 本地进程 与 远程进程 的 动态库 地址 偏移量 , 计算出 远程进程 动态库 的 函数地址 ;
三、远程调用 目标进程 linker 中的 dlsym 函数 获取 注入的 libbridge.so 动态库中的 load 函数地址
参考 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 ) 博客 , 通过
设置 EIP 寄存器 , 设置要执行的函数指令地址 ;
设置 ESP 寄存器 , 设置要执行的函数参数的栈内存 ;
可以远程调用执行指定的方法 ;
四、远程调用 目标进程 中的 libbridge.so 动态库中的 load 函数
下面是 libbridge.so 动态库的代码 , 在该换行代码中 , 只是调用 dlopen 函数加载了真正的 libnative.so 动态库 , 这个动态库是进行逆向操作的主要的库 , 执行核心逻辑 ;
先远程注入 libbridge.so 动态库 , 然后远程调用 libbridge.so 中的 load 函数 , 将真正的 libnative.so 加载到目标进程中 ;
使用修改寄存器的方法 强行加载 libbridge.so 动态库 , 会影响目标进程的布局 , 因此这个动态库越小越好 , 并且 使用完毕后 , 马上关闭该动态库 , libbridge.so 动态库只起一个敲门的作用 , libnative.so 加载完成后 , 直接将 libbridge.so 动态库干掉 , 过河拆桥 ;
#include <unistd.h> #include <jni.h> #include <dlfcn.h> #include <android/log.h> #define LOG_TAG "DongNao" #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) int load() { LOGW("%s(%d):%s\n", __FILE__, __LINE__, __FUNCTION__); void* handle = dlopen("/data/system/debug/libnative.so", RTLD_GLOBAL); LOGW("%s(%d):%s handle=%p\n", __FILE__, __LINE__, __FUNCTION__, handle); void* invoke = dlsym(handle, "invoke"); LOGW("%s(%d):%s invoke=%p\n", __FILE__, __LINE__, __FUNCTION__, invoke); ((void(*)())invoke)(); return 0; }