在运行时获取可用的库函数

时间:2019-01-15 10:03:48

标签: c++ shared-libraries

我正在使用Windows上的动态链接库(.dll)或Linux上的共享对象(.so)。

我的目标是编写一些代码,这些代码可以-提供磁盘上库的绝对路径-返回该库的所有导出函数(导出表)的列表,并最终能够调用这些函数。在Windows(wit dll)和Linux(with so)上都可以使用。

我正在编写一种包装器,该包装器将函数调用委托给相应的库。因此,我收到一个路径,一个函数名以及一个参数列表,然后我要转发这些参数。问题是:在尝试调用给定函数之前,我想知道给定函数是否存在

here中,我发现了一种与平台无关的打开和关闭库的方法,以及获得了具有给定名称的函数的指针。
因此剩下的就是首先获得可用函数的名称。

在这个主题上,我发现this question仅在需要Linux特定解决方案的情况下处理相同类型的问题。在给定的答案中说

  

没有libc函数可以做到这一点。但是,您可以自己编写(或从readelf之类的工具复制/粘贴代码)。

这清楚地表明,有一些工具可以满足我的需求。唯一的问题是,是否有一个既可以在Windows上也可以在Linux上运行的软件?如果没有,我将如何独自解决?


Here是一个C#实现(实际上这是我要移植到C ++的代码),可以做我想做的事情(尽管仅Windows)。在我看来,这似乎是手动处理库结构。如果要这样做,那我在哪里可以找到有关图书馆结构的必要信息?

2 个答案:

答案 0 :(得分:1)

因此,在unixoids上(Linux和WinNT都具有posix子系统),dlopen函数可用于加载动态库并按名称获取指向 known 符号的函数指针该符号的符号。

据我所知,获取符号列表从来都不是POSIX想要指定的一个方面,因此,长话短说,可以在Linux上为您完成的功能特定于那里使用的libc(GNU libc,主要是),然后在Windows上使用的libc。可移植代码意味着必须为两个不同的libcs​​使用不同的代码库!

如果不想依赖libc,则必须有一个 binary object parser (对于Linux上的ELF共享库,对于Windows上的PE),以从中读取符号名称文件。实际上有很多这样的东西-显然,WINE的PE具有可移植性(尤其是在Linux上也可以移植),并且Linux下的每个链接器(包括glibc的运行时链接器)都可以解析ELF文件。

就个人而言,radare2是一个很好的反向工程框架,具有大量的语言绑定,实际上旨在分析二进制文件,并为您提供导出的符号(以及能够提取未导出的函数,构造调用图等)。 )。它确实具有调试器,即也具有跳入功能的功能。

答案 1 :(得分:1)

所以,现在知道

  

我正在编写一种包装器,该包装器将函数调用委托给相应的库。因此,我收到一个路径,一个函数名以及一个参数列表,然后我要转发这些参数。问题是:在尝试调用给定函数之前,我想知道给定函数是否存在

事情变得更容易了:您实际上不需要获取出口清单。尝试起来既简单又快捷。

因此,在任何POSIX系统上(包括Windows的POSIX子系统和Linux),dlopen将打开该库并加载符号表,而dlsym将在其中查找符号表。如果该符号不在表中,则仅返回NULL。因此,您已经拥有了您认为需要的所有表格;只是不明确,而是可查询的。