Muszę znaleźć offset miejscowym symbolem w udostępnionej biblioteki na OS X. Lokalnej jako symbol w niewyspecjalizowanych eksportowane symbolem. Dlatego dyld("symbol_name")
nie będzie działać.Znalezienie Przesunięcia z symboli lokalnych w Shared Libraries programowo na OS X
mogę jednak użyć nm
znaleźć te przesunięcia, na przykład
$ nm /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/DesktopServicesPriv | grep -e ChildSetLabel -e NodeVolumeEject
000000000006cccd T _NodeVolumeEject
000000000009dbd7 t __ChildSetLabel
Nie widzimy eksportowane (T
) symbol NodeVolumeEject
który jest przesunięcie 0x6cccd
mogę łatwo ujawniają wykorzystaniem dyld("NodeVolumeEject")
. dyld()
ujawni adres w aktualnej przestrzeni adresowej, ale jestem zadowolony z przesunięcia we wspólnej bibliotece lub z bezwzględnego adresu w przestrzeni adresowej. Dodatkowo istnieje lokalna (t
) symbol _ChildSetLabel
który jest przesunięcie (0x9dbd7
) nie mogę ujawnić za pomocą dyld()
.
Chciałbym móc to zrobić programowo rozdzielczość (bez gobjdump
, nm
, otool
ani żadnego innego zewnętrznego programu). Czy istnieje "łatwy" sposób, aby to osiągnąć? Kod źródłowy wyżej wymienionych narzędzi zawiera potrzebny kod, ale zastanawiam się, czy nie ma czegoś prostszego.
domeny: Rozwiązanie jest tylko do pracy na OS X 10.8 lub wyższy dla x86_64 macho plików binarnych.
Wyjaśnienie: Byłbym szczęśliwy, aby dowiedzieć się bezwzględna przesunięcie w prądzie offsetowego (które ze względu na ASLR) nie jest statyczna oczywiście. Ale cieszę się również z obliczenia przesunięcia w stosunku do początku tej biblioteki, która pozostaje statyczna (do ponownej kompilacji). Część z „adres w bibliotece” na „adres w przestrzeni adresowej” jest dość proste:
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 */
}
To, jak długo _ChildSetLabel
i NodeVolumeEject
są w tej samej wspólnej biblioteki wystarczy. Dlatego ASLR nie stanowi tutaj problemu.