Поиск смещений локальных символов в общих библиотеках программно в OS X

Мне нужно найти смещение локального символа в общей библиотеке на 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()

Я хотел бы иметь возможность сделать это разрешение программно (без,gobjdumpnmotoolили любая другая внешняя программа). Есть "легко" способ достичь этого? Исходный код инструментов, упомянутых выше, содержит необходимый код, но мне интересно, есть личто-то более простое.

Домен: решение должно работать только на OS X 10.8 или выше для двоичных файлов x86_64 MachO.

Пояснение: я был бы рад выяснить абсолютное смещение в текущем смещении (которое из-за 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 здесь не проблема.

Ответы на вопрос(1)

Ваш ответ на вопрос