:定位
我想解析链接到二进制文件特定部分(而不是共享库)的所有符号的签名。
我做了什么
在汇编中,您可以定义section .example
(NASM语法),然后使用以下命令将其链接到二进制文件中的特定位置:
exampleStart = .;
*(.example)
exampleEnd = .;
这允许我使用exampleStart
和exampleEnd
迭代所有符号,只要我知道它们是什么。例如,如果我知道所有符号都是不需要参数并且什么都不返回的方法,我可以将它们转换为void(*)()
并将它们称为方法。
问题
.section
语法?示例
下面我想展示一下我想要实现的一些例子(伪C ++):
SECTION example
void somePrefix_myFunction() {
// ...
}
int somePrefix_anotherFunction(int a, int b) {
return a + b;
}
ENDSECTION
在其他地方,我希望能够迭代本节中的符号,并获得符号的位置和签名。
答案 0 :(得分:1)
假设通过说 binary 你的意思是一个可执行文件,你通常无法从linux 1 上的可执行文件中加载符号 - 必须编写C ++代码或重构为(共享)库。然后,您就可以致电dlopen
和dlsym
加载相关的符号。
剩下的问题是如何找到符号?当您从汇编转移到C ++,并且您的问题被标记为这样时,您将对符号编码的大部分控制作为汇编标签放弃到编译器和链接器。例如,您将不得不考虑诸如C ++名称修改之类的内容。枚举名称的最佳方法是调用nm
列出所有符号并解析输出以提取您感兴趣的符号名称 - 据我所知,没有nm
调用您的linux API也可以打电话给自己。你需要考虑太多特定的文件格式知识,在linux上嵌入不同版本的链接器和可执行文件中的符号。
编辑。您表示nm
不是一个选项。鉴于此限制,我认为您将不得不求助于手动维护符号列表。否则,您正在考虑复制基本上do_lookup
在 glibc 中执行的操作,因为它会遍历链接映射。
另请注意,您可能需要使用extern "C"
标记符号以避免名称损坏,并且能够理智地维护所讨论的符号列表。
<子> 1 除了PIE可执行文件的特殊情况。 子>