如何检测当前进程卸载动态库?
How do you detect the unloading of a dynamic library in the current process?
在Windows上,我们可以通过LdrDllNotification注册一个回调函数,这样当任何一个DLL即将被卸载时,我们就可以有机会收集一些关于那个DLL的有用信息,包括地址、大小等
我对类 UNIX 平台(包括 Linux、macOS、iOS、Android 等)了解不够。我怎样才能在这些平台上做同样的事情?
在 Linux 上,库由 dynamic loader. The loading is usually done automatically when needed by the loader itself, but can also be done manually using the library function dlopen()
. The unloading is done manually through dlclose()
加载和卸载,或者在程序退出时自动加载和卸载。这并不普遍适用于所有 Unix 系统,但仅适用于 POSIX 兼容的系统。
不幸的是,因为(不像Windows)加载和卸载库的工作是由动态加载器(它只是一个用户空间库)执行的,内核不知道发生了什么,不提供任何检测动态库加载或卸载的机制。更不幸的是,加载器本身也不提供任何这样的机制。事实上,除了使用指标或类似的东西之外,这些功能可能几乎没有用处。
您通常甚至不会在 Linux 的 运行 时间卸载库,除非我们谈论的是一个非常复杂的软件,需要在 运行 时限制其内存占用]宁。加载程序在启动时需要时加载库(或调用第一个需要的库函数时),然后它们像任何其他内存一样留给内核在程序结束时清理。
据我所知,您在 Linux 上检测动态库卸载的“最佳”方法是:
创建您自己的共享库实现 dlclose()
并在 运行 可执行文件时 预加载 它。这是解释 here and here.
继续观看/proc/self/maps
解析加载库列表。
运行 像gdb
这样的调试器下的程序,可以scripted/automated using Python.
根据其他操作系统...Android 是基于 Linux 的,但它具有额外的安全功能并且应用程序是沙盒的,除非您对设备进行 root 或使用调试 shell 你不能只是“运行”其他应用程序与自定义 dlclose()
甚至调试器挂钩。关于 iOS 我不能说太多,但我怀疑考虑到应用程序的能力非常有限(也被沙盒化),实现这样的功能甚至不是一个选择。 AFAIK macOS 还支持手动 loading/unloading 库的 dlopen()
/dlclose()
,但是链接器与 Linux(上面链接)上常用的链接器不同,所以我可以'关于自动 loading/unloading 行为就不多说了。
在Windows上,我们可以通过LdrDllNotification注册一个回调函数,这样当任何一个DLL即将被卸载时,我们就可以有机会收集一些关于那个DLL的有用信息,包括地址、大小等
我对类 UNIX 平台(包括 Linux、macOS、iOS、Android 等)了解不够。我怎样才能在这些平台上做同样的事情?
在 Linux 上,库由 dynamic loader. The loading is usually done automatically when needed by the loader itself, but can also be done manually using the library function dlopen()
. The unloading is done manually through dlclose()
加载和卸载,或者在程序退出时自动加载和卸载。这并不普遍适用于所有 Unix 系统,但仅适用于 POSIX 兼容的系统。
不幸的是,因为(不像Windows)加载和卸载库的工作是由动态加载器(它只是一个用户空间库)执行的,内核不知道发生了什么,不提供任何检测动态库加载或卸载的机制。更不幸的是,加载器本身也不提供任何这样的机制。事实上,除了使用指标或类似的东西之外,这些功能可能几乎没有用处。
您通常甚至不会在 Linux 的 运行 时间卸载库,除非我们谈论的是一个非常复杂的软件,需要在 运行 时限制其内存占用]宁。加载程序在启动时需要时加载库(或调用第一个需要的库函数时),然后它们像任何其他内存一样留给内核在程序结束时清理。
据我所知,您在 Linux 上检测动态库卸载的“最佳”方法是:
创建您自己的共享库实现
dlclose()
并在 运行 可执行文件时 预加载 它。这是解释 here and here.继续观看
/proc/self/maps
解析加载库列表。运行 像
gdb
这样的调试器下的程序,可以scripted/automated using Python.
根据其他操作系统...Android 是基于 Linux 的,但它具有额外的安全功能并且应用程序是沙盒的,除非您对设备进行 root 或使用调试 shell 你不能只是“运行”其他应用程序与自定义 dlclose()
甚至调试器挂钩。关于 iOS 我不能说太多,但我怀疑考虑到应用程序的能力非常有限(也被沙盒化),实现这样的功能甚至不是一个选择。 AFAIK macOS 还支持手动 loading/unloading 库的 dlopen()
/dlclose()
,但是链接器与 Linux(上面链接)上常用的链接器不同,所以我可以'关于自动 loading/unloading 行为就不多说了。