如何查看 .so 文件中存在哪些模块?

如何查看 .so 文件中存在哪些模块?

我正在尝试理解 Linux 和*.so文件。这很难。
我试图弄清楚,如何找到文件中可用的模块*.so,例如:

在我的 httpd 配置文件中我发现了以下行: LoadModule wsgi_module modules/mod_wsgi.so

我认为wsgi_module是“内部”的一个模块mod_wsgi.so
问题:如何列出或查找*.so文件的所有模块?

答案1

一般来说,所有.so文件(无论是库还是模块)都是通过导出命名的符号– 通常表示函数或有时表示“外部”变量 – 程序将使用“动态链接器”按名称导入这些变量。大多模块与库相同。

对于 Apache httpd 模块,“模块名称”wsgi_module实际上只是 .so 文件导出的符号的名称(最有可能指向一个结构变量,该变量包含指向 Apache 开始将其用作模块所需的所有函数的指针)。主程序将使用 加载 .sodlopen()并使用 查找指定的符号dlsym()

(对于使用 .so 模块的其他程序,情况可能会有所不同,因为每个程序基本上都有自己的特点;例如,许多程序希望所有模块都提供一个符号相同的每次都说出名字。

要查看 .so 文件导出的名称,您可以使用nmbinutils:

$ nm -D -Ux /usr/lib/httpd/modules/mod_rewrite.so 
0000000000012020 D rewrite_module

这里-D使 nm 显示“动态”符号,并将-U列表修剪为仅“定义”的符号(即导出 - 完整列表还包含正在进口来自其他图书馆)。

(根据一切,它应该只是-U,而不是-Ux,但显然我拥有的 nm/binutils 版本错误地要求为短选项提供一个参数,所以我不得不使用-Usomething。长选项--defined-only按预期工作。)

你可以将它与.so一个普通的 C 库文件进行比较,它的工作方式大致相同(符号是通常完成后在编译时解析gcc hello.c -lcrypt,但也可以使用 dlsym 加载):

$ nm -D -Ux /usr/lib/libcrypt.so
0000000000000000 A XCRYPT_2.0
0000000000000000 A XCRYPT_4.3
0000000000000000 A XCRYPT_4.4
0000000000010e30 T crypt@@XCRYPT_2.0
0000000000011090 T crypt_checksalt@@XCRYPT_4.3
000000000000f4d0 T crypt_gensalt@@XCRYPT_2.0
0000000000011000 T crypt_gensalt_ra@@XCRYPT_2.0
0000000000010e50 T crypt_gensalt_rn@@XCRYPT_2.0
0000000000011120 T crypt_preferred_method@@XCRYPT_4.4
0000000000010de0 T crypt_r@@XCRYPT_2.0
0000000000010d20 T crypt_ra@@XCRYPT_2.0
0000000000010c90 T crypt_rn@@XCRYPT_2.0

的替代方案nm,来自David的评论:

答案2

您的假设是错误的:.so文件只是通过链接一个或多个目标文件创建的共享库。

具体来说, LoadModule 指令 语法如下:

LoadModule module filename

该指令的描述如下:

LoadModule 指令链接目标文件或库文件名,并将名为 module 的模块结构添加到活动模块列表中。Module 是文件中 module 类型的外部变量的名称,并在模块文档中列为模块标识符。

这意味着这module是 Apache 中使用的特定名称。并非所有.so库都是 Apache 模块,而且它们肯定不是由 Apache 模块组成的。

.so库由链接器从目标文件创建。有时这些文件也称为“模块”。一旦链接完成,它们就不能再解压到其原始目标文件中,因为这些信息不再可用。

库中剩下的只有.so原始对象文件提供的入口点以及它们最初所属的对象文件的名称。但是,如果不反汇编库,您就无法猜测每个对象文件的代码从哪里开始或结束。

相关内容