dlopen'ing 时是否运行静态初始化(和/或其他)代码?

ein*_*ica 5 c++ shared-objects dynamic-loading dlopen static-initialization

当您dlopen()是共享对象时,是否有一种机制可以让该 DLL 中的代码在不被显式调用的情况下执行?具体来说,调用者dlopen()可能不知道的全局变量/静态变量的 C++ 静态初始化代码?我很确定答案应该是“是”,但我不记得是什么机制导致这种情况发生,以及如何利用它来运行任意代码。

Emp*_*ian 4

是:dlopen遵循 ELF 二进制格式机制在加载时运行代码。

实际上有两种这样的机制:

  • 较旧的使用特殊.init和s 部分,其中包含用于和调用的.fini函数指针数组。由于这些部分在运行时可能不存在,因此还有指向相应部分的动态标签。dlopendlcloseDT_INITDT_FINI
  • 较新的机制是.init_array.fini_array以及对应的DT_INIT_ARRAYDT_INIT_ARRAYSZDT_FINI_ARRAYDT_FINI_ARRAYSZ动态标签。

此处描述了两种机制之间的差异。

上升到源代码级别,如果您用 修饰 C 函数 __attribute__((constructor)),编译器将使用这两种机制之一来使其在对象被dlopen编辑时运行。需要动态初始化的全局 C++ 对象的构造代码也是如此。