c++ - 在nm符号值中,C++ 偏移?

  显示原文与译文双语对照的内容
73 5

为了给你一些上下文,这里是我所尝试实现的内容: 为了在. so 文件本身中具有版本字符串,我在共享目标文件中嵌入了一个 const char* 。 我正在做数据分析,这个字符串让我能够让数据知道所产生的软件版本。 这一切都正常。

当我尝试直接从. so 库中读取字符串时,我的问题是。 我试图用


nm libSMPselection.so | grep _version_info



然后


000000000003d968 D __SMPselection_version_info



这一切都很好,并且如预期的( 这个 char* 叫做 _SMPselection_version_info ) 。 然而,我希望现在能够打开文件,找到 0 x3d968并开始读取我的字符串,但只有垃圾。

打开. so 文件并简单搜索字符串( 我知道它是怎么开始的)的内容时,我可以在地址 0 x2e0b4处找到它。 在这个地址,零终止,按预期。 ( 目前我正在使用这种方法。)

我不是电脑科学家。 如果不是符号的地址,请告诉我为什么is显示的符号值不正确或者不同。

( 我正在使用 OSX 10.7的Mac机)

时间: 原作者:

61 5

没有人建议最简单的方法: 进行二进制操作,动态加载你的lib ( 在 命令行 上给它命名) 并为符号( 也可以在 命令行 上找到) 转换 dlsym(),并将它的输出到 stdout 。

135 3

假定它的一个,或者similarily结构化二进制文件,你必须考虑加载物料的地址。

在二进制上使用 objdump -Fd,你可以让反汇编程序显示符号的精确文件偏移。

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

接下来要小心的是,看看它是否是间接字符串,这是否可以使用 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


...



因此我们在文件中查看 0 x8cf4d0,并在hexeditor中查找:


008C:F4D0 D8 C1 89 00 00 00 00 00 01 00 00 00 FF FF FF FF



所以,我们在那里采取 0 x89C1D8,减去 0 x400000并且有 0 x49c1d8,当我们在那里找到的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



这意味着"trunk_8043"。

YMMV,特别是它的他文件格式,但是这是一般的方式,这些事件的结构与特殊情况。

93 1

在Linux上,有'字符串'命令可以帮助你从二进制文件中提取字符串。

http://linux.about.com/library/cmd/blcmdl1_strings.htm

在 HPUX ( 我想在其他Unix风格中) 中,有类似的命令调用'what'。 它只提取以"@ ( # ) 开头的字符串,但如果你控制字符串的内容,则这不是问题。

...