代码不复杂,原理是动态解析自身内存里面的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);
}
}