zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

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

2023-09-14 09:07:30 时间





一、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;
}