Closed flx413 closed 7 months ago
还有个疑问是 dl_iterate_phdr 和 /proc/self/maps 可以拿到当前进程已经加载的所有共享对象,是不是也有可能不是最新的?比如我遍历 /proc/self/maps 的每一行,假如遍历的中途有个新的动态库加载,会出现遍历不到这个动态库的情况吗
嗯,确实存在这个问题,感谢指出。这个其实是“首次refresh”和“dlopen监听机制完成启动之前”的间隙。也许可以在bytehook初始化的最后阶段调用一下bh_task_manager_init_dl_monitor
,然后再调用一次refresh,这样在初始化完成后就不会出现这个问题了。
bytehook比较早的内部版本是在初始化时就执行dlopen监听和refresh的,后来为了加快初始化速度,才这样调整的。后续版本我研究下怎么弥补这个问题。。。
还有个疑问是 dl_iterate_phdr 和 /proc/self/maps 可以拿到当前进程已经加载的所有共享对象,是不是也有可能不是最新的?比如我遍历 /proc/self/maps 的每一行,假如遍历的中途有个新的动态库加载,会出现遍历不到这个动态库的情况吗
是的,单纯遍历maps是有可能有这种问题。bytehook在dlopen监听机制启动后应该就不会有这个问题了。
感觉作者一直在吃老本啊,都是之前开源工程的那一套
我在线上使用 bhook,版本 v1.0.3,想 hook 一个动态下载的 so,发现会有 so 已经加载好,但是 bhook 没有自动去 hook 的问题,出现概率比较低。
我找到了一种复现场景,发现是 bhook 没有立即监听到动态库的加载,所以也没有 hook 了: 1.线程 1 去初始化 bhook,调用 Bytehook.init,并且调用 bytehook_hook_single; 2.线程 2 加载某一个 so;
复现的环境和代码我也贴出来:
bhook 版本:v1.0.3 机型:OnePlus6,Android 10
我改了一些代码,让问题复现:
大致的流程是 bhook 会先 hook dlopen 系列函数,会先调用一遍 bh_elf_manager_refresh 把当前的 so 信息缓存起来,然后执行 hook dlopen 的任务;如果中途有别的 so 加载,bhook 会漏掉这些新的 so,相当于没监听到。 有个补救措施是 如果后续有新的 so 加载会调用 dlopen,就会触发 bh_elf_manager_refresh 再刷一遍缓存,之前漏掉的 so 也会加进来并且执行它们的 hook 任务,这样表现的情况就是 hook 被延后了。假如后续没有触发 bh_elf_manager_refresh,那么这次的 hook 就失败了
我感觉这种情况无法完全避免,如果对可靠性要求高的话,我可以每隔一段时间调用 refresh 吗?就像 xhook 的那种用法一样