// search by iteration. Doesn't work on iOS
Module.enumerateSymbols('libxpc.dylib', {
onMatch(symbol) {
if (symbol.name == '_xpc_connection_call_event_handler') {
console.log(symbol.address);
return 'stop';
}
},
onError() {
console.error('error');
},
onComplete() {
console.log('complete');
}
})
// This works
console.log(DebugSymbol.getFunctionByName('_xpc_connection_call_event_handler'))
// on macOS, they both work, but the second approach is slower
So this function reads LC_SYMTAB from mach header, and parses nlist to get symbols:
However, many symbols are stored locally in dyld_shared_cache (or more recent versions, they are moved to .symbols file)
struct dyld_cache_header
{
char magic[16]; // e.g. "dyld_v0 i386"
// ...
uint64_t localSymbolsOffset; // file offset of where local symbols are stored
uint64_t localSymbolsSize; // size of local symbols information
uint8_t uuid[16]; // unique value for each shared cache file
};
Test case
So this function reads
LC_SYMTAB
from mach header, and parses nlist to get symbols:https://github.com/frida/frida-gum/blob/097dd4197074c5566664e5668fd49db97bfd06dc/gum/gumdarwinmodule.c#L781
However, many symbols are stored locally in dyld_shared_cache (or more recent versions, they are moved to
.symbols
file)Here are some references:
https://github.com/jmpews/Dobby/blob/b0176de574104726bb68dff3b77ee666300fc338/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.cpp#L46
https://github.com/blacktop/ipsw/blob/f03db0abba66f0af93d55344b791f57fde39db42/pkg/dyld/image.go#L795