Ich muss den Offset eines lokalen Symbols in einer gemeinsam genutzten Bibliothek auf OS X finden. Lokales Symbol wie bei nicht exportiertem Symbol. Daher wird dyld("symbol_name")
nicht funktionieren.Offsets von lokalen Symbolen in freigegebenen Bibliotheken programmatisch unter OS X suchen
Ich kann aber nm
nutzen diese Offsets zu finden, zum Beispiel
$ nm /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/DesktopServicesPriv | grep -e ChildSetLabel -e NodeVolumeEject
000000000006cccd T _NodeVolumeEject
000000000009dbd7 t __ChildSetLabel
Dort sehen wir die exportierte (T
) Symbol NodeVolumeEject
die 0x6cccd
versetzt ist ich leicht dyld("NodeVolumeEject")
offenbaren verwenden. dyld()
wird die Adresse im aktuellen Adressraum offenbaren, aber ich bin glücklich mit dem Offset in der gemeinsam genutzten Bibliothek oder der absoluten Adresse im Adressraum. Zusätzlich gibt es das lokale (t
) Symbol _ChildSetLabel
welches Offset ist (0x9dbd7
) Ich kann nicht aufdecken dyld()
.
Ich möchte diese Auflösung programmgesteuert (ohne gobjdump
, nm
, otool
oder ein anderes externes Programm) tun können. Gibt es einen "einfachen" Weg, das zu erreichen? Der Quellcode der oben erwähnten Tools enthält den benötigten Code, aber ich frage mich, ob es etwas einfacher gibt.
Domäne: Die Lösung muss nur unter OS X 10.8 oder höher für x86_64 MachO-Binärdateien ausgeführt werden.
Klarstellung: Ich würde gerne den absoluten Offset im aktuellen Offset herausfinden (der aufgrund von ASLR) nicht offensichtlich statisch ist. Aber ich bin auch glücklich, den Offset relativ zu dem Anfang dieser Bibliothek herauszufinden, die statisch bleibt (bis zum Neukompilieren). Der Teil von „Adresse in der Bibliothek“ auf „Adresse im Adressraum“ ist ganz einfach:
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 */
}
Dies ist, solange _ChildSetLabel
und NodeVolumeEject
genug in dem gleichen Shared Library ist. Daher ist ASLR hier kein Problem.