刚报了一个错误 java.lang.UnsatisfiedLinkError: dlopen failed: /data/app/xx/lib/arm/libxx.so: has text relocations
1、dlopen 动态库失败原因,我碰到主要是以下几点(碰到新问题之后再完善,先打个点) ①动态库位置没有放对地方,dlopen 时候找不到你想操作的动态库 解决办法:放到指定目录。 if((handle = dlopen(myso, RTLD_NOW)) == NULL) { printf("dlopen - %sn", dlerror());
报错如下: [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed 2021-02-18 10:52:42.189834+0800
mac本地安装mysql后,navicat连接报错: 2059 - Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen
报错:E/art: dlopen("/data/app/com.itep.mt.dispatch-1/lib/arm/libCommunication.so", RTLD_LAZY) failed: dlopen
文章目录 一、EIP 寄存器指向 dlopen 函数 二、ESP 寄存器指向栈内存 三、调试程序收回目标进程控制权 一、EIP 寄存器指向 dlopen 函数 ---- 代码段中 , 一般都有 dlopen 函数 , 该函数属于 system/lib/linker 模块 , 这是一个 so 库 ; dlopen 函数的作用是加载一个动态库 , 并返回动态链接库的句柄 包含头文件 : #include <dlfcn.h > 函数原型 : void * dlopen( const char * pathname, int mode); 将 EIP 寄存器指向 dlopen 函数 , 也就是将 dlopen 函数的地址设置到 EIP 寄存器中 ; 目标进程 恢复运行后 , 就会执行 dlopen 函数 ; 二、ESP 寄存器指向栈内存 ---- 除了函数外 , 还要传递参数 , 在 x86 架构中 , 函数参数是通过 栈 , 用于存放函数的参数 ; 将 S 内存作为 栈 : 将 S 内存的首地址赋值给 ESP 寄存器 ; 三、调试程序收回目标进程控制权 ---- 在 dlopen 函数执行完毕后 , 调试程序 需要将
而byOpen不仅支持fake dlopen方式从maps加载,还可以将还没加载到maps的so库绕过系统限制强行加载进来使用,实现更加通用化的dlopen。 增强版fake dlopen 关于fake dlopen的方式实现,网上已有很多实现,比如: Nougat_dlfunctions Enhanced_dlfunctions byOpen参考了里面的实现 过程只有一次malloc分配(省去整个符号表的内存分配和copy) 兼容原始dlopen,如果是低版本android系统,没有限制,还是会优先切到原生dlopen上去直接调用 Android例子 Android iOS 虽然ios可以直接使用dlopen,但是审核上会有风险,苹果有可能会对提交AppStore的app扫描相关dlopen/dlsym等调用,来判断是否存在一些敏感的私有调用。 接口用法 相关静态库和接口在:dlopen.h 相关使用方式跟原生dlopen完全相同: typedef by_char_t const* (*curl_version_t)(); by_pointer_t
文章目录 一、dlopen 函数简介 二、获取 目标进程 linker 中的 dlopen 函数地址 三、远程调用 目标进程 linker 中的 dlopen 函数 一、dlopen 函数简介 ---- dlopen 函数的作用是 打开一个 so 动态库 , 并返回该 so 的句柄 ; 包含头文件 : #include<dlfcn.h> 函数原型 : void * dlopen( const char pathname : 动态库的路径 , Android 系统文件的绝对路径 ; ② int mode : 动态库的打开法方式 ; void* 返回值 : 动态库句柄 二、获取 目标进程 linker 中的 dlopen 方法 : /* 调用 目标进程 的 dlopen 函数 , dlopen_addr 是 libbridge.so 的地址 , 注意分析 dlopen 参数含义 此处就是 注入 libbridge.so 动态库 */ if (ptrace_call_wrapper(target_pid, "dlopen", dlopen_addr, parameters, 2, ®s) == -1) 参考 【
,dlsym函数的绝对地址; 0x04 获取并保存目标进程的堆栈,设置dlopen函数的相关参数,将要注入的SO的绝对路径压栈; 0x05 调用dlopen函数; 0x03 获取目标进程的dlopen,dlsym函数的绝对地址: 大概思路是这样的:首先通过遍历/proc/pid/maps文件分别得到本进程中dlopen函数所在动态库的基地址local_module_base 和目标进程dlopen函数所在动态库的基地址remote_module_base,接着获取本进程dlopen函数的绝对地址local_addr = (void*)dlopen。 0x05 调用dlopen函数: 参数设置好后,设置ARM_pc = dlopen_addr, ARM_lr = 0。 (注:dlopen_addr为0x03获取到的目标进程dlopen函数的绝对地址,ARM_lr = 0的目的在于当目标进程执行完dlopen函数,使目标进程发生异常,从而让本进程重新获得控制权) 0x06
AndroidRuntime: FATAL EXCEPTION: main Process: kim.hsl.webp, PID: 11165 java.lang.UnsatisfiedLinkError: dlopen
2019-11-11 23:37:00.153893: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154058: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154212: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154358: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154507: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen
2019-11-11 23:37:00.153893: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154058: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154212: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154358: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen 2019-11-11 23:37:00.154507: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Could not dlopen
这里android调用了android_dlopen_ext方法,来实现动态库的加载,返回dlextinfo,而非android的,则是调用dlopen加载的。 04 在bionic/linker里面的Android.mk文件,发现了一段注释,可以解释__dl_android_dlopen_ext和android_dlopen_ext 怎么变化的。 这里的--prefix-symbols=__dl_ 就是给名字的符号上面加入一个前缀,于是我们的android_dlopen_ext 就变成了__dl_android_dlopen_ext。 我们打断点,发现b android_dlopen_ext 和 b __dl_android_dlopen_ext 是一个位置(bionic/linker/dlfcn.cpp line 82).所以我们实际的 android_dlopen_ext就是__dl_android_dlopen_ext,也就是dlfcn.cpp文件内容了。
.\3.js结果如下:发现闪退,老样子,按照之前的思路,我们可以先 hook dlopen 方法,监控动态库的加载情况。 dlopen 原型函数:void *dlopen(const char *filename, int flag);参数 说明 代码如下:function hook_dlopen() { var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext "); Interceptor.attach(android_dlopen_ext, { onEnter: function (args) { var path_ptr -> leave") } });}hook_dlopen()可以看到,程序虽然在我们的 libmsaoaidsec.so 退出了,但是在这之前加载了一个 libDexHelper.so
查看哪个.so文件在检测hook,运行var dlopen_ext = Module.findExportByName(null, "android_dlopen_ext"); if (dlopen_ext () { const dlopen = Module.findExportByName(null, "dlopen") || Module.findExportByName (null, "__loader_dlopen"); if (! dlopen) { console.log("Failed to find dlopen"); return; } Interceptor.attach 检测 libexec.so 和 libexecmain.so var dlopen = Module.findExportByName(null, "dlopen"); if (dlopen
if (isAppModule && IsExistedPath(pathKey)) { Dl_namespace ns = nsMap_[pathKey]; lib = dlopen_ns (&ns, path, RTLD_LAZY); } else { lib = dlopen(path, RTLD_LAZY); }#endif EmplaceModuleLib return lib;}LoadModuleLibrary() 方法里先尝试从缓存中取,如果缓存有则直接返回否则根据不同的平台做不同方式的加载,以 LINUX_PLATFORM 平台为例,直接调用系统的 dlopen () 方法加载共享库并把句柄返回,dlopen() 方法简单说明如下:dlopen() 方法是一个在 Unix-like 系统(包括 Linux)中用于动态加载共享库(.so 文件)的函数,它允许程序在运行时动态地加载和卸载共享库 当使用 dlopen() 方法加载一个共享库(.so 文件)时,它会执行该库中所有的全局构造函数(也称为初始化函数),这些构造函数通常用于初始化库中的静态数据或执行其他一次性设置。
dlopen源码 android_dlopen_ext源码 function hook_dlopen() { var dlopen = Module.findExportByName(null , "dlopen"); Interceptor.attach(dlopen, { onEnter: function (args) { var so_name retval) { if (this.call_hook) hookTest2(); } }); // 高版本Android系统使用android_dlopen_ext var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext"); Interceptor.attach (android_dlopen_ext, { onEnter: function (args) { var so_name = args[0].readCString
main { jniLibs.srcDirs = ['libs'] } } 03-13 17:03:51.021 13400-13400/com.itep.mt.dispatch E/art: dlopen ("/data/app/com.itep.mt.dispatch-1/lib/arm/libgwqsmc.so", RTLD_LAZY) failed: dlopen failed: library " libQt5Core.so" not found java.lang.UnsatisfiedLinkError: dlopen failed: library "libQt5Core.so" not
return process.dlopen(module, path.toNamespacedPath(filename)); }; 直接调了process.dlopen,该函数在node.js里定义。 const rawMethods = internalBinding('process_methods'); process.dlopen = rawMethods.dlopen; 找到process_methods env->SetMethod(target, "dlopen", binding::DLOpen); 之前说过,node的拓展模块其实是动态链接库,那么我们先看看一个动态链接库我们是如何使用的。 bool DLib::Open() { handle_ = dlopen(filename_.c_str(), flags_); if (handle_ ! 分析到这,我们回到DLOpen函数。
mmaps 文件 , 可以获取 工具程序 ( 调试进程 ) 的 libc.so 的起止地址 , 也可以获取 目标进程 ( 被调试进程 ) 的 libc.so 的起止地址 ; 在 libc.so 中存在 dlopen 函数 , dlopen 函数有一个函数指针 ( 函数地址 ) , 该函数指针可以直接获取到 , dlopen 的名称就代表该函数的地址 , libc.so 的起始地址可以通过 /proc/pid/mmaps 文件确定 , dlopen 函数在 libc.so 的相对偏移量 ( 如 : 8 字节 ) 也是确定的 , 这样就可以知道 dlopen 函数在内存中的地址 ; 获取到 dlopen 函数地址后 , 将 IP 寄存器设置成 r_dlopen 函数地址 ; IP 寄存器存储将要执行的下一条指令的偏移量 ; 通过 mmap 函数 , 分配一块新内存 , SP 寄存器指向这块新内存 , 之后 调用 ptrace