understanding dyld offsets in runtime

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

understanding dyld offsets in runtime

Postby westwost » Wed Nov 11, 2015 2:52 pm

I'm trying to understand how to parse the symbol table in runtime, by finding the LC_SYMTAB command and extracting the symoff and stroff values. I add these values to the base address of the cache and suppose to receive the address of the symbol table and string table.

The problem is when I work on ios9 and arm64 device. The values in these fields are way higher than expected, and when I use my algorithm (which works on 32bit devices) it works fine.

Anyone heard about it? or knows how to find the read the stroff and symoff values ?
westwost
 
Posts: 2
Joined: Wed Nov 11, 2015 2:46 pm

Re: understanding dyld offsets in runtime

Postby morpheus » Wed Nov 11, 2015 3:44 pm

Jtool does that, and I can spare you a lot of heartache by linking you with mach lib... The relevant code you're looking for is

Code: Select all
struct symtabent *MachOGetSymbols (unsigned char *MachO, uint32_t Size, uint32_t *numsyms)
{

        if (!g_symTab)
        {
              // Assume you have a process function which parses the LC's and gets you the lc_symtab
                process64 (MachO,  // unsigned char *MachO64,
                           Size,   // uint32_t Size,
                           0);     // uint64_t Offset);
        }
        if (!g_symTab)
        {    // Won't happen.
                printf("Something doesn't work\n");
                return (NULL);
        }

        struct symtab_command *sc = (struct symtab_command *) g_symTab;


        if (!sc ) return (NULL);

    struct symtabent *st =  NULL;
     {
        int sym = 0;
         st= (struct symtabent *) malloc ((sc->nsyms +1) * sizeof(struct symtabent));

        struct nlist_64 *nlist_entry =  (struct nlist_64 *) (MachO + sc->symoff);
        *numsyms = sc->nsyms;
        for (sym = 0 ; sym < sc->nsyms; sym++)
        {

                if (nlist_entry->n_un.n_strx)
                { if (nlist_entry->n_value)
                        {
                                st[sym].ptr = nlist_entry->n_value;
                                strncpy (st[sym].sym , MachO+nlist_entry->n_un.n_strx + sc->stroff, MAX_SYM_LEN);
                        }
                nlist_entry++;

                }

        }
        }



Though it sounds to me like it would work for you as is if it works on 32-bit, and you just need to make sure you're using uint64_t's and not uint32_t's.
morpheus
Site Admin
 
Posts: 532
Joined: Thu Apr 11, 2013 6:24 pm

Re: understanding dyld offsets in runtime

Postby westwost » Thu Nov 12, 2015 9:01 am

Thanks for the quick reply.. The problem is that all of the addressing looks pretty weird.

For example I'm trying to locate the LINKEDIT segment by parsing the LC_SEGMENT_64 that holds the LINKEDIT string, and I look at the vmaddr value (uint64).
I'll take the RawCamera lib for example:

dyld_cache is loaded into 0x182dc0000
RawCamera is loaded into 0x183e4000

LC_SEGMENT_64 with LINKEDIT str has in its vmaddr field the address 0x1a0de5000, which is beyond what I expect it to be (and points to an unmapped memory).
Again, on 32bit, it all works fine =\
westwost
 
Posts: 2
Joined: Wed Nov 11, 2015 2:46 pm

Re: understanding dyld offsets in runtime

Postby morpheus » Thu Nov 12, 2015 4:20 pm

At this point, all I can do is ask for code; The snippet above is direct from JTool, and I have yet to see a single case where it doesn't work (well, I saw plenty, but then weeded out the bugs and retested :-)

It's very likely a bug in your code, but - sans code - I've no idea where it might be.
morpheus
Site Admin
 
Posts: 532
Joined: Thu Apr 11, 2013 6:24 pm


Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 1 guest

cron