frida / frida-gum

Cross-platform instrumentation and introspection library written in C
https://frida.re
Other
727 stars 240 forks source link

`Module.enumerateSymbols` missed lots of local symbols from iOS dyld_shared_cache #770

Open ChiChou opened 8 months ago

ChiChou commented 8 months ago

Test case


// 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:

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)

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
};

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