When using APIs such as MSHookFunction, it is often important to able to reach into the core of another program's logic, changing behaviors that are not part of its public API. Unfortunately, standard dynamic loader symbol functionality (dlsym and dladdr) only can access these exported symbols.

Some platforms offer alternatives (such as nlist on Darwin), however these are both highly platform dependent, and sometimes even broken in specific instances (such as 64-bit Mac OS X, or recent versions of iOS); these issues dramatically limit their usefulness

Substrate therefore provides an alternative and standardized API that can be used on all of its supported platforms to perform these low-level lookups of private names and symbols. It ties together with MSGetImageByName to allow looking up symbols from specific libraries.

As you might not know what library a symbol you are looking for is in, this API supports passing NULL as the image parameter to mean "search all images". However, as the same symbol may be present in multiple libraries (and you will want a specific one), you should not rely on this in production.

Note: On iOS, Substrate itself hooks nlist and "upgrades" its functionality to be usable in combination with ASLR and the dyld shared cache. However, this is only for backwards compatibility with extensions written before iOS 3.1: developers should use the more portable MSFindSymbol instead.

void *MSFindSymbol(MSImageRef image, const char *name);
Parameter Description
image Either a valid image reference (as returned by a previous call of MSGetImageByName) or NULL, to indicate "any image".
name Name of a raw image symbol to search for. This is not a high-level symbol as used by dlopen: it might require prefixed underscores or other platform-specific mangling.
return Address of symbol (adjusting as typical for ARM/Thumb) or NULL if the symbol could not be located.
MSImageRef image;
image = MSGetImageByName("/usr/lib/libSystem.B.dylib");

void *(*palloc)(size_t);
palloc = (void *(*)(size_t)) MSFindSymbol(image, "_malloc");

void *data = (*palloc)(1024);
free(data);