是否可以以编程方式获取共享库中函数的签名? [英] Is it possible to get the signature of a function in a shared library programmatically?

查看:42
本文介绍了是否可以以编程方式获取共享库中函数的签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题很明确,我们可以通过dl_open等方式加载一个库.

The title is clear, we can loaded a library by dl_open etc..

但是我怎样才能得到里面函数的签名呢?

But how can I get the signature of functions in it?

推荐答案

这个答案一般无法回答.从技术上讲,如果您使用详尽的调试信息编译了可执行文件(代码可能仍然是优化的发布版本),那么该可执行文件将包含额外的部分,从而提供某种二进制文件的反射性.在 *nix 系统上(您提到了 dl_open),这是通过 DWARFELF 二进制文件的额外部分中调试数据.类似它适用于 MacOS X 上的 Mach Universal Binaries.

This answer cannot be answered in general. Technically if you compiled your executable with exhaustive debugging information (code may still be an optimized, release version), then the executable will contain extra sections, providing some kind of reflectivity of the binary. On *nix systems (you referred to dl_open) this is implemented through DWARF debugging data in extra sections of the ELF binary. Similar it works for Mach Universal Binaries on MacOS X.

然而,Windows PE 使用完全不同的格式,所以不幸的是,DWARF 不是真正的跨平台(实际上在我的 3D 引擎的早期开发阶段,我为 Windows 实现了一个 ELF/DWARF 加载程序,以便我可以使用通用格式引擎的各种模块,因此可以通过一些认真的努力来完成).

Windows PEs however uses a completely different format, so unfortunately DWARF is not truley cross plattform (actually in the early development stages of my 3D engine I implemented an ELF/DWARF loader for Windows, so that I could use a common format for the engines various modules, so with some serious effort such can be done).

如果您不想实现自己的加载器或调试信息访问器,那么您可以通过一些引用函数名称表的额外符号(通过某些标准命名方案)嵌入反射信息,映射到他们的签名.在 C 源文件的情况下,编写解析器以从源文件本身提取信息是相当简单的.众所周知,C++ OTOH 很难正确解析,因此您需要一些成熟的编译器才能正确解析.为此目的,开发了 GCCXML,技术上是一种 GCC,它以 XML 形式而不是二进制对象发出 AST.发出的 XML 则更容易解析.

If you don't want to go into implementing your own loaders, or debugging information accessors, then you may embed the reflection information through some extra symbols exported (by some standard naming scheme) which refer to a table of function names, mapping to their signature. In the case of C source files writing a parser to extract the information from the source file itself is rather trivial. C++ OTOH is so notoriously difficult to parse correctly, that you need some fully fledged compiler to get it right. For this purpose GCCXML was developed, technically a GCC that emits the AST in XML form instead of an object binary. The emitted XML then is much easier to parse.

从提取的信息中创建一个带有某种链表/数组/等的源文件.描述每个功能的结构.如果您不直接导出每个函数的符号,而是使用函数指针初始化反射结构中的某些字段,您将获得一个非常漂亮且干净的带注释的导出方案.从技术上讲,您也可以将此信息放在二进制文件的单独部分,但将其放在只读数据部分也可以.

From the extracted information create a source file with some kind of linked list/array/etc. structure describing each function. If you don't directly export each function's symbol but instead initialize some field in the reflection structure with the function pointer you got a really nice and clean annotated exporting scheme. Technically you could place this information in a spearate section of the binary as well, but putting it in the read only data section does the job as well, too.

然而,如果给你一个 3rd 方二进制文件——比如说最坏的情况,它是从 C 源代码编译的,没有调试信息,并且所有没有外部引用的符号都被剥离了——你就完蛋了.您能做的最好的事情是对函数访问可以传递参数的各个位置的方式进行一些二进制分析.

However if you're given a 3rd party binary – say worst case scenario it has been compiled from C source, no debugging information and all symbols not externally referenced stripped – you're pretty much screwed. The best you could do, was applying some binary analysis of the way the function accesses the various places in which parameters can be passed.

这只会告诉您参数的数量和每个参数值的大小,而不是类型或名称/含义.在对某些程序(例如恶意软件分析或安全审计)进行逆向工程时,识别传递给函数的参数的类型和含义是主要工作之一.最近我遇到了一些驱动程序,为了调试目的我不得不反转,你无法相信我在 Linux 内核模块中发现 C++ 符号这一事实是多么震惊(你不能在 Linux 内核中以理智的方式使用 C++),但也松了口气,因为 C++ 名称修改为我提供了大量信息.

This will only tell you the number of parameters and the size of each parameter value, but not the type or name/meaning. When reverse engineering some program (e.g. malware analysis or security audit), identifying the type and meaning of the parameters passed to functions is one of the major efforts. Recently I came across some driver I had to reverse for debugging purposes, and you cannot believe how astounded I was by the fact that I found C++ symbols in a Linux kernel module (you can't use C++ in the Linux kernel in a sane way), but also relieved, because the C++ name mangling provided me with plenty information.

这篇关于是否可以以编程方式获取共享库中函数的签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆