Search code examples
iphoneiosuuiddwarf

How to get mach-o uuid of a running process?


to get UUID on mac i can use

dwarfdump -u path/to/compile/executable

also i can get UUID with simple crash in 'Binary Images' section

Is the way to get UUID without crash on ios device?


Solution

  • An executable's (mach-o file) UUID is created by the linker ld and is stored in a load command named LC_UUID. You can see all load commands of a mach-o file using otool:

    otool -l path_to_executable
    
    > ...
    > Load command 8
    >      cmd LC_UUID
    >  cmdsize 24
    >     uuid 3AB82BF6-8F53-39A0-BE2D-D5AEA84D8BA6
    > ...
    

    Any process can access its mach-o header using a global symbol named _mh_execute_header. Using this symbol you can iterate over the load commands to search LC_UUID. The payload of the command is the UUID:

    #import <mach-o/ldsyms.h>
    
    NSString *executableUUID()
    {
        const uint8_t *command = (const uint8_t *)(&_mh_execute_header + 1);
        for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx) {
            if (((const struct load_command *)command)->cmd == LC_UUID) {
                command += sizeof(struct load_command);
                return [NSString stringWithFormat:@"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
                        command[0], command[1], command[2], command[3],
                        command[4], command[5],
                        command[6], command[7],
                        command[8], command[9],
                        command[10], command[11], command[12], command[13], command[14], command[15]];
            } else {
                command += ((const struct load_command *)command)->cmdsize;
            }
        }
        return nil;
    }