【问题标题】:Iterate over all symbols in a specific section and obtain their signatures遍历特定部分中的所有符号并获取它们的签名
【发布时间】:2014-03-04 10:15:42
【问题描述】:

目标

我想解析链接到我的二进制文件(不是共享库)的特定部分的所有符号的签名。

我做了什么

在汇编中,您可以定义 section .example(NASM 语法),然后使用以下命令将其链接到我的二进制文件中的特定位置:

exampleStart = .;
*(.example)
exampleEnd = .;

这允许我使用exampleStartexampleEnd 遍历所有符号,只要我知道它们是什么。例如,如果我知道所有符号都是不需要参数且不返回任何内容的方法,我可以将它们强制转换为 void(*)() 并将它们作为方法调用。

问题

  1. 有没有办法在 C++ 中定义节,类似于 NASM 中的 .section 语法?
  2. 我可以告诉链接器创建一个符号表之类的东西,它还包含方法的签名吗?

一个例子

在下面我想展示一个我想要实现的小例子(伪C++):

SECTION example

void somePrefix_myFunction() {
    // ...
}

int somePrefix_anotherFunction(int a, int b) {
    return a + b;
}

ENDSECTION

然后我希望能够在其他地方迭代本节中的符号并获取符号的位置和签名。

【问题讨论】:

    标签: c++ linker ld symbols


    【解决方案1】:

    假设说 binary 是指可执行文件,则通常无法从 linux 上的可执行文件中加载符号1 - 必须编写 C++ 代码或重构为(共享)库。然后你就可以调用dlopendlsym来加载相关的符号了。

    剩下的问题是如何定位符号?当您从汇编转移到 C++ 并且您的问题被标记为这样时,您放弃了对编译器和链接器作为汇编标签的符号编码的大部分控制。例如,您将不得不考虑诸如 C++ 名称修饰之类的事情。枚举名称的最佳方法是调用nm 列出所有符号并解析输出以提取您感兴趣的符号名称 - 据我所知,没有nm 调用的Linux API,您也可以自己调用.否则,您必须考虑太多特定的文件格式知识,才能在 linux 上枚举不同版本的链接器和可执行文件中的符号。


    编辑。您指出nm 不是一个选项。鉴于此限制,我认为您将不得不求助于手动维护符号列表。否则,您正在查看在 glibc 中复制 do_lookup 在遍历链接图时所做的基本工作。

    另外请注意,您可能必须用extern "C" 标记您的符号以避免名称混乱,并能够合理地维护讨论的符号列表。


    1 除了 PIE 可执行文件的特殊情况。

    【讨论】:

    • 感谢您的回答。通过二进制,我的意思是一个普通的精灵二进制(这是由引导加载程序作为内核加载的)。所以没有像nm这样的工具,另一种方法是自己读取.elf-header,但是有没有办法让链接器为我的符号生成某种附加信息?
    • @m4xdev 它必须是链接器吗?由于您编写了加载二进制文件的代码,您不能与二进制解析器和加载器共享binary.h 头文件吗? (这就是库在 C++ 中的典型使用方式——您可以使用它们的头文件。)
    • 应该知道现有链接器符号的代码实际上与符号在同一个二进制文件中。我想列出这些符号并使用那里的名称以进一步使用符号背后的方法
    • @m4xdev 然后您可以有一个已知的符号名称,您可以使用dlsym 加载它,它会返回您必须随后使用dlsym 加载的所有其他名称的列表。您可以通过对方法使用 extern "C" 来避免重整。添加方法时,您必须将其添加到列表中。由于这都是一个二进制文件,因此您确实知道所有名称的签名(如函数指针签名),但在添加或删除方法时必须继续维护该列表。
    • 嗯,但维护方法列表正是我想要避免的。想象一下有一个 register(char*,void*) 方法以某种方式注册我的方法。到目前为止,我必须为我添加的每个新函数手动调用该方法。就像,有一个很大的“registerAll”方法,然后为每个函数调用 register。从另一个角度来看,您是否知道一种方法可以让预处理器列出所有例如用另一个宏标记的方法?
    猜你喜欢
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 2017-06-07
    • 2012-09-14
    相关资源
    最近更新 更多