我需要在 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 在这里不是问题。