偏移的nm符号值?

Sim*_*mon 7 c++ unix macos linker nm

只是为了给你一些上下文,这是我想要实现的:我在一个共享对象文件中嵌入一个const char*,以便在.so文件本身中有一个版本字符串.我正在进行数据分析,这个字符串使我能够让数据知道产生它的软件版本.一切正常.

我遇到的问题是当我尝试直接读取.so库中的字符串时.我试着用

nm libSMPselection.so | grep _version_info
Run Code Online (Sandbox Code Playgroud)

得到

000000000003d968 D __SMPselection_version_info
Run Code Online (Sandbox Code Playgroud)

这一切都很好并且符合预期(char*被称为_SMPselection_version_info).但是我本来希望现在能够打开文件,寻找0x3d968并开始读取我的字符串,但我得到的只是垃圾.

当我打开.so文件并只是搜索字符串的内容(我知道它是如何开始)时,我可以在地址0x2e0b4找到它.在这个地址它就在那里,零终止并按预期.(我现在正在使用这种方法.)

我不是计算机科学家.有人可以向我解释为什么nm所示的符号值不正确,或者不同的是,如果它不是符号的地址,那么符号值是多少?

(顺便说一句,我在使用OSX 10.7的Mac上工作)

Pla*_*aHH 7

假设它是一个ELF或类似结构的二进制文件,你必须考虑加载东西的地址,这受到ELF头中的东西的影响.

objdump -Fd在二进制文件上使用,您可以让反汇编程序也显示符号的确切文件偏移量.

使用objdump -x你可以找到这个加载器地址,通常是标准linux可执行文件的0x400000.

接下来要注意的是查看它是否是间接字符串,这可以通过使用来轻松完成objdump -g.当字符串被发现为间接字符串时,在objdump -Fd您输出的位置将找不到字符串,而是找到地址.从这里你需要再次减去加载器地址.让我给你看一个我的二进制文件的例子:

objdump -Fd BIN | grep VersionString
  45152f:       48 8b 1d 9a df 87 00    mov    0x87df9a(%rip),%rbx        # ccf4d0 <acVersionString> (File Offset: 0x8cf4d0)

objdump -x BIN
...
LOAD off    0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**12
...
Run Code Online (Sandbox Code Playgroud)

所以我们查看文件中的0x8cf4d0并在hexeditor中找到:

008C:F4D0 D8 C1 89 00  00 00 00 00  01 00 00 00  FF FF FF FF
Run Code Online (Sandbox Code Playgroud)

所以我们在那里取0x89C1D8,减去0x400000并得到0x49c1d8,当我们在hexeditor中查看时,我们发现:

0049:C1D0 FF FF 7F 7F  FF FF 7F FF  74 72 75 6E  6B 5F 38 30
0049:C1E0 34 33 00 00  00 00 00 00  00 00 00 00  00 00 00 00
Run Code Online (Sandbox Code Playgroud)

这意味着"trunk_8043".

YMMV,尤其是当它的其他一些文件格式时,但这是关于这些东西如何构造的一般方式,有很多疣和细节偏离特殊情况.


sel*_*rer 2

没有人建议最简单的方法:做一个动态加载你的库的二进制文件(在命令行上给它名称)并为你的符号执行 dlsym() (或者它也可以在命令行上得到它)将其转换为字符串指针并将其打印到标准输出。

  • 这是一个好主意。我现在正在尝试。只有一个问题:我正在测试的库对其他库有相当长的依赖链。如果我尝试使用 dlopen 加载它们,我会收到符号未找到错误。我感兴趣的版本字符串当然没有依赖项。如何让 dl 忽略依赖关系? (2认同)