Skip to content

Instantly share code, notes, and snippets.

@EthanArbuckle
Created January 20, 2025 05:22
Show Gist options
  • Save EthanArbuckle/fdd469c913502327bafe073c630e0090 to your computer and use it in GitHub Desktop.
Save EthanArbuckle/fdd469c913502327bafe073c630e0090 to your computer and use it in GitHub Desktop.
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#include <mach-o/dyld_images.h>
#include <dlfcn.h>
static void *dyld_for_each_installed_shared_cache;
static void *dyld_shared_cache_for_each_image;
static void *dyld_image_get_installname;
static void *dyld_image_local_nlist_content_4Symbolication;
static const char *swift_demangle(const char *mangled_name) {
static void *swift_demangle_ptr = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
swift_demangle_ptr = dlsym(RTLD_DEFAULT, "swift_demangle");
});
if (swift_demangle_ptr == NULL || mangled_name == NULL) {
return NULL;
}
size_t output_size = 0;
return ((char *(*)(const char *, size_t, char *, size_t *, uint32_t))swift_demangle_ptr)(mangled_name, strlen(mangled_name), NULL, &output_size, 0);
}
static void *swift_dlsym(const char *symbol_name) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
void *handle = dlopen("/usr/lib/system/libdyld.dylib", RTLD_LAZY);
dyld_for_each_installed_shared_cache = dlsym(handle, "dyld_for_each_installed_shared_cache");
dyld_shared_cache_for_each_image = dlsym(handle, "dyld_shared_cache_for_each_image");
dyld_image_get_installname = dlsym(handle, "dyld_image_get_installname");
dyld_image_local_nlist_content_4Symbolication = dlsym(handle, "dyld_image_local_nlist_content_4Symbolication");
});
__block void *found_symbol = NULL;
((void (*)(void (^)(void *)))dyld_for_each_installed_shared_cache)(^(void *cache) {
((void (*)(void *, void (^)(void *)))dyld_shared_cache_for_each_image)(cache, ^(void *image) {
((bool (*)(void *, void (^)(const void *, uint64_t, const char *)))
dyld_image_local_nlist_content_4Symbolication)(image, ^(const void *nlistStart, uint64_t nlistCount, const char *stringTable) {
const struct nlist_64 *symTab = (const struct nlist_64 *)nlistStart;
for (uint64_t i = 0; i < nlistCount && !found_symbol; i++) {
const char *mangled_name = &stringTable[symTab[i].n_un.n_strx];
if (symTab[i].n_un.n_strx == 0) {
continue;
}
if (strcmp(mangled_name, symbol_name) == 0) {
found_symbol = (void *)symTab[i].n_value;
return;
}
if (mangled_name[0] == '_' && strcmp(mangled_name + 1, symbol_name) == 0) {
found_symbol = (void *)symTab[i].n_value;
return;
}
const char *demangled = swift_demangle(mangled_name);
if (demangled) {
if (strstr(demangled, symbol_name)) {
found_symbol = (void *)symTab[i].n_value;
printf("'%s' matched to:\n mangled: %s\n demangled: %s\n", symbol_name, mangled_name, demangled);
}
free((void *)demangled);
}
if (found_symbol) {
return;
}
}
});
});
});
return found_symbol;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment