【发布时间】:2013-07-01 00:33:24
【问题描述】:
我需要在 OS X 上的共享库中找到本地符号的偏移量。本地符号与非导出符号中的一样。因此dyld("symbol_name") 将不起作用。
但是,我可以使用nm 来查找这些偏移量,例如
$ nm /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/DesktopServicesPriv | grep -e ChildSetLabel -e NodeVolumeEject
000000000006cccd T _NodeVolumeEject
000000000009dbd7 t __ChildSetLabel
我们看到导出的 (T) 符号 NodeVolumeEject 偏移 0x6cccd 我可以使用 dyld("NodeVolumeEject") 轻松显示。 dyld() 将显示当前地址空间中的地址,但我对共享库中的偏移量或地址空间中的绝对地址感到满意。此外,还有一个本地 (t) 符号 _ChildSetLabel 是偏移量 (0x9dbd7) 我无法使用 dyld() 显示。
我希望能够以编程方式解决此问题(无需 gobjdump、nm、otool 或任何其他外部程序)。有没有一种“简单”的方法来实现这一目标?上面提到的工具的源代码包含所需的代码,但我想知道是否没有更简单的东西。
域:该解决方案仅适用于 x86_64 MachO 二进制文件的 OS X 10.8 或更高版本。
澄清:我很乐意找出当前偏移量中的绝对偏移量(由于 ASLR)显然不是静态的。但我也很高兴找出相对于该库开始的偏移量,该库保持静态(直到重新编译)。从“库中的地址”到“地址空间中的地址”的部分很简单:
off_t sym_offset_child_set_label = ANSWER_TO_THIS_QUESTION("_ChildSetLabel");
Dl_info info;
void *abs_volume_eject = dlsym(RTLD_DEFAULT, "NodeVolumeEject");
void *abs_child_set_label = NULL;
if (dladdr(abs_volume_eject, &info)) {
abs_child_set_label = (void *)((char *)info.dli_fbase + sym_offset_child_set_label);
/* abs_child_set_label now points to the function in question */
}
这是,只要_ChildSetLabel 和NodeVolumeEject 在同一个共享库中就足够了。因此,ASLR 在这里不是问题。
【问题讨论】:
标签: macos shared-libraries mach-o dyld