标题很清楚,我们可以通过以下方式加载库dl_open
etc..
但是我怎样才能得到其中函数的签名呢?
这个答案不能笼统地回答。从技术上讲,如果您使用详尽的调试信息编译可执行文件(代码可能仍然是优化的发布版本),则可执行文件将包含额外的部分,从而提供二进制文件的某种反射性。在 *nix 系统上(您提到dl_open
)这是通过实现DWARF http://en.wikipedia.org/wiki/DWARF调试额外部分中的数据ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format二进制。类似它适用于马赫通用二进制文件在 MacOS X 上。
然而,Windows PE 使用完全不同的格式,因此不幸的是 DWARF 并不是真正的跨平台(实际上,在我的 3D 引擎的早期开发阶段,我为 Windows 实现了一个 ELF/DWARF 加载程序,以便我可以为各种引擎使用通用格式模块,因此通过一些认真的努力就可以做到这一点)。
如果您不想实现自己的加载器或调试信息访问器,那么您可以通过导出的一些额外符号(通过某种标准命名方案)嵌入反射信息,这些符号引用函数名称表,映射到它们的函数名称表。签名。对于 C 源文件,编写解析器从源文件本身提取信息是相当简单的。 C++ OTOH 非常难以正确解析,因此您需要一些成熟的编译器才能正确解析。为此,开发了 GCCXML,从技术上讲,GCC 以 XML 形式而不是对象二进制形式发出 AST。这样发出的 XML 就更容易解析。
从提取的信息中创建一个带有某种链接列表/数组/等的源文件。描述每个功能的结构。如果您不直接导出每个函数的符号,而是使用函数指针初始化反射结构中的某些字段,那么您将获得一个非常漂亮且干净的带注释的导出方案。从技术上讲,您也可以将此信息放在二进制文件的单独部分中,但将其放在只读数据部分中也可以完成这项工作。
然而,如果你得到一个第 3 方二进制文件——比如说最坏的情况,它是从 C 源代码编译的,没有调试信息,并且所有符号都没有被外部引用——你就完蛋了。您能做的最好的事情就是对函数访问可以传递参数的各个位置的方式进行一些二进制分析。
这只会告诉您参数的数量和每个参数值的大小,但不会告诉您类型或名称/含义。当对某些程序进行逆向工程(例如恶意软件分析或安全审计)时,识别传递给函数的参数的类型和含义是主要工作之一。最近,我遇到了一些出于调试目的而必须逆向运行的驱动程序,你无法相信我在 Linux 内核模块中发现 C++ 符号这一事实让我感到多么惊讶(你不能以正常的方式在 Linux 内核中使用 C++) ),但也松了一口气,因为 C++ 名称修饰为我提供了充足的信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)