iOS防护----获取Mach-O文件的UUID

代码不复杂,原理是动态解析自身内存里面的macho文件,根据macho文件格式找到LC_UUID然后就能得到uuid的值:

#include <mach-o/dyld.h>

static const char* uuidBytesToString(const uint8_t* uuidBytes) {
    CFUUIDRef uuidRef = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes*)uuidBytes));
    NSString* str = (__bridge_transfer NSString*)CFUUIDCreateString(NULL, uuidRef);
    CFRelease(uuidRef);
    
    return str == NULL ? NULL : strdup(str.UTF8String);
}

void getUUID(int index) {
    int offset = 0;
    struct mach_header_64 * header = (struct mach_header_64 *)_dyld_get_image_header(index);
    if(header->magic != MH_MAGIC_64) {
        return ;
    }
    offset = sizeof(struct mach_header_64);
    int ncmds = header->ncmds;
    while(ncmds--) {
        struct load_command * lcp = (struct load_command *)((uint8_t*)header + offset);
        offset += lcp->cmdsize;
        if (lcp->cmd == LC_UUID) {
            struct uuid_command * uuid = (struct uuid_command *)lcp;
            printf("%s %s \n", uuidBytesToString(uuid->uuid), _dyld_get_image_name(index));
            break;
        }
    }
}

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
        getUUID(0);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

如果想获取所有动态库的UUID,其实也很简单,就是获取到 APP 中所有的 image count,然后一个个遍历获取header、Load Command,进而找到所有 Mach-O 的 UUID:

void getAllUUID() {
    int imageCount = (int)_dyld_image_count();
    for (int i = 0; i < imageCount; ++i) {
        struct mach_header_64* header = (struct mach_header_64*)_dyld_get_image_header((unsigned)i);
        if(header->magic != MH_MAGIC_64) {
            return ;
        }
        getUUID(i);
    }
}

猜你喜欢

转载自blog.csdn.net/youshaoduo/article/details/107414623