开源框架OpenUDID源码和伪源码分析

源码加上翻译是

// Private method to create and return a new OpenUDID
// Theoretically, this function is called once ever per application when calling [OpenUDID value] for the first time.
// After that, the caching/pasteboard/redundancy mechanism inside [OpenUDID value] returns a persistent and cross application OpenUDID
//
//创建并返回新OpenUDID的私有方法

//理论上,当第一次调用[OpenUDID value]时,每个应用程序都会调用此函数一次。

//之后,[OpenUDID value]中的缓存/粘贴板/冗余机制返回一个持久的、跨应用程序的OpenUDID
+ (NSString*) _generateFreshOpenUDID {
    
    NSString* _openUDID = nil;
    //2011年8月:有一天,iOS可能不再允许这样做。如果是这样的话,就把这一行注释掉。
    
    //2012年3月25日:这一天到了,让我们删除这个“非法”的电话。。。
    
    //2012年8月:好吧,也许什么都不做;无论如何,WWDC2012给了我们一些东西来工作;请看下面
    // August 2011: One day, this may no longer be allowed in iOS. When that is, just comment this line out.
    // March 25th 2012: this day has come, let's remove this "outlawed" call...
    // August 2012: well, perhaps much ado about nothing; in any case WWDC2012 gave us something to work with; read below
#if TARGET_OS_IPHONE	
//    if([UIDevice instancesRespondToSelector:@selector(uniqueIdentifier)]){
//        _openUDID = [[UIDevice currentDevice] uniqueIdentifier];
//    }
#endif
    
    //
    // !!!!! IMPORTANT README !!!!!
    //
    // August 2012: iOS 6 introduces new APIs that help us deal with the now deprecated [UIDevice uniqueIdentifier]
    // Since iOS 6 is still pre-release and under NDA, the following piece of code is meant to produce an error at
    // compile time. Accredited developers integrating OpenUDID are expected to review the iOS 6 release notes and
    // documentation, and replace the underscore ______ in the last part of the selector below with the right
    // selector syntax as described here (make sure to use the right one! last word starts with the letter "A"):
    // https://developer.apple.com/library/prerelease/ios/#documentation/UIKit/Reference/UIDevice_Class/Reference/UIDevice.html
    //
    // !!!!! 重要自述!!!!!
    
    //
    
    //2012年8月:iOS 6引入了新的api,帮助我们处理现在被弃用的[UIDevice uniqueIdentifier]
    
    //由于iOS 6仍然是预发行版,并且在NDA下,下面的代码将在
    
    //编译时。集成OpenUDID的合格开发人员将审查iOS 6发行说明和
    
    //文档,并将下面选择器最后部分的下划线替换为右侧
    
    //这里描述的选择器语法(确保使用正确的语法!最后一个字以字母“A”)开头:
    
    // The semantic compiler warnings are still normal if you are compiling for iOS 5 only since Xcode will not
    // know about the two instance methods used on that line; the code running on iOS will work well at run-time.
    // Either way, it's time that you junped on the iOS 6 bandwagon and start testing your code on iOS 6 ;-)
    //
    // WHAT IS THE SIGNIFICANCE OF THIS CHANGE?
    //
    // Essentially, this means that OpenUDID will keep on behaving the same way as before for existing users or
    // new users in iOS 5 and before. For new users on iOS 6 and after, the new official public APIs will take over.
    // OpenUDID will therefore be obsoleted when iOS reaches significant adoption, anticipated around mid-2013.
    //如果只为iOS 5编译,语义编译器警告仍然是正常的,因为Xcode不会
    
    //了解这一行中使用的两个实例方法;在iOS上运行的代码在运行时可以很好地工作。
    
    //不管怎样,现在是时候让你沉迷于iOS 6的潮流,开始在ios6上测试你的代码了;-)
    
    //
    
    //这一变化的意义何在?
    
    //
    
    //本质上,这意味着OpenUDID将继续以与以前相同的方式对现有用户或
    
    //iOS5及之前的新用户。对于iOS 6及以后的新用户,新的官方公共api将接管。
    
    //因此,当iOS在2013年年中被广泛采用时,OpenUDID将被淘汰。
    /*

        September 14; ok, new development. The alleged API has moved!
        This part of the code will therefore be updated when iOS 6 is actually released.
        Nevertheless, if you want to go ahead, the code should be pretty easy to
        guess... it involves including a .h file from a nine-letter framework that ends
        with the word "Support", and then assigning _openUDID with the only identifier method called on the sharedManager of that new class... don't forget to add
        the framework to your project!
     9月14日;好的,新的发展。所谓的API已经移动了!
     
     因此,这部分代码将在iOS 6实际发布时更新。
     
     不过,如果您想继续,代码应该很容易
     
     猜猜看。。。它包括一个9个字母的框架中的.h文件
     
     使用“支持”一词,然后使用在该新类的sharedManager上调用的唯一标识符方法分配openUDID。。。别忘了加上
     
     你的项目框架!
#if TARGET_OS_IPHONE
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
        _openUDID = [[[UIDevice currentDevice] identifierForA_______] UUIDString];
# error                                                         ^ read comments above, fix accordingly, and remove this #error line
    }
#endif
    
     */
    
    // Next we generate a UUID.
    // UUIDs (Universally Unique Identifiers), also known as GUIDs (Globally Unique Identifiers) or IIDs
    // (Interface Identifiers), are 128-bit values guaranteed to be unique. A UUID is made unique over 
    // both space and time by combining a value unique to the computer on which it was generated—usually the
    // Ethernet hardware address—and a value representing the number of 100-nanosecond intervals since 
    // October 15, 1582 at 00:00:00.
    // We then hash this UUID with md5 to get 32 bytes, and then add 4 extra random bytes
    // Collision is possible of course, but unlikely and suitable for most industry needs (e.g. aggregate tracking)
    //
    //接下来我们生成一个UUID。
    
    //uuid(通用唯一标识符),也称为guid(全局唯一标识符)或iid
    
    //(接口标识符)是保证唯一的128位值。UUID在
    
    //空间和时间都是通过组合计算机所特有的值来生成的,通常
    
    //以太网硬件地址和一个值,表示自
    
    //1582年10月15日00:00:00。
    
    //然后我们用md5散列这个UUID,得到32个字节,然后再添加4个随机字节
    
    //当然,碰撞是可能的,但不太可能,而且适合大多数行业的需要(例如,聚合跟踪)
    
    //
    if (_openUDID==nil) {
        CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
        CFStringRef cfstring = CFUUIDCreateString(kCFAllocatorDefault, uuid);
        const char *cStr = CFStringGetCStringPtr(cfstring,CFStringGetFastestEncoding(cfstring));
        unsigned char result[16];
        CC_MD5( cStr, strlen(cStr), result );
        CFRelease(uuid);
        CFRelease(cfstring);

        _openUDID = [NSString stringWithFormat:
                @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%08x",
                result[0], result[1], result[2], result[3], 
                result[4], result[5], result[6], result[7],
                result[8], result[9], result[10], result[11],
                result[12], result[13], result[14], result[15],
                     (NSUInteger)(arc4random() % NSUIntegerMax)];  
    }
    
    //给开源社区中的其他开发人员打电话:
    
    //
    
    //请随意建议更好或替代的“UDID”生成代码以上。
    
    //注意,目标不是寻找更好的散列方法,而是寻找分散的方法(即,不是基于web的方法)
    
    //160位/20字节的随机字符串生成器,可能的冲突最少。
    
    //
    // Call to other developers in the Open Source community:
    //
    // feel free to suggest better or alternative "UDID" generation code above.
    // NOTE that the goal is NOT to find a better hash method, but rather, find a decentralized (i.e. not web-based)
    // 160 bits / 20 bytes random string generator with the fewest possible collisions.
    // 

    return _openUDID;
}


// Main public method that returns the OpenUDID
// This method will generate and store the OpenUDID if it doesn't exist, typically the first time it is called
// It will return the null udid (forty zeros) if the user has somehow opted this app out (this is subject to 3rd party implementation)
// Otherwise, it will register the current app and return the OpenUDID
//
//返回OpenUDID的主公共方法

//如果OpenUDID不存在,这个方法将生成并存储它,通常是在第一次调用它时

//如果用户以某种方式选择了此应用程序,它将返回空udid(40个零)(这取决于第三方实现)

//否则,它将注册当前应用程序并返回OpenUDID

//
+ (NSString*) value {
    return [OpenUDID valueWithError:nil];
}

+ (NSString*) valueWithError:(NSError **)error {

    if (kOpenUDIDSessionCache!=nil) {
        if (error!=nil)
            *error = [NSError errorWithDomain:kOpenUDIDDomain
                                         code:kOpenUDIDErrorNone
                                     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID in cache from first call",@"description", nil]];
        return kOpenUDIDSessionCache;
    }
    
  	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    // The AppUID will uniquely identify this app within the pastebins
    //AppUID将在pastebins中唯一标识此应用程序
    

    NSString * appUID = [defaults objectForKey:kOpenUDIDAppUIDKey];
    if(appUID == nil)
    {
      // generate a new uuid and store it in user defaults
        CFUUIDRef uuid = CFUUIDCreate(NULL);
        appUID = (NSString *) CFUUIDCreateString(NULL, uuid);
        CFRelease(uuid);
        [appUID autorelease];

    }
  
    NSString* openUDID = nil;
    NSString* myRedundancySlotPBid = nil;
    NSDate* optedOutDate = nil;
    BOOL optedOut = NO;
    BOOL saveLocalDictToDefaults = NO;
    BOOL isCompromised = NO;
    
    // Do we have a local copy of the OpenUDID dictionary?
    // This local copy contains a copy of the openUDID, myRedundancySlotPBid (and unused in this block, the local bundleid, and the timestamp)
    //
    //我们有OpenUDID字典的本地副本吗?
    
    //此本地副本包含openUDID、myRedundancySlotPBid的副本(在此块中未使用、本地bundleid和时间戳)
    id localDict = [defaults objectForKey:kOpenUDIDKey];
    if ([localDict isKindOfClass:[NSDictionary class]]) {
        localDict = [NSMutableDictionary dictionaryWithDictionary:localDict]; // we might need to set/overwrite the redundancy slot
        openUDID = [localDict objectForKey:kOpenUDIDKey];
        myRedundancySlotPBid = [localDict objectForKey:kOpenUDIDSlotKey];
        optedOutDate = [localDict objectForKey:kOpenUDIDOOTSKey];
        optedOut = optedOutDate!=nil;
        OpenUDIDLog(@"localDict = %@",localDict);
    }
    
    // Here we go through a sequence of slots, each of which being a UIPasteboard created by each participating app
    // The idea behind this is to both multiple and redundant representations of OpenUDIDs, as well as serve as placeholder for potential opt-out
    //
    //在这里,我们将浏览一系列的插槽,每个插槽都是每个参与应用程序创建的UIPasteboard
    
    //其背后的思想是同时使用openudid的多个和冗余表示,以及作为潜在退出的占位符
    NSString* availableSlotPBid = nil;
    NSMutableDictionary* frequencyDict = [NSMutableDictionary dictionaryWithCapacity:kOpenUDIDRedundancySlots];
    for (int n=0; n<kOpenUDIDRedundancySlots; n++) {
        NSString* slotPBid = [NSString stringWithFormat:@"%@%d",kOpenUDIDSlotPBPrefix,n];
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
        UIPasteboard* slotPB = [UIPasteboard pasteboardWithName:slotPBid create:NO];
#else
        NSPasteboard* slotPB = [NSPasteboard pasteboardWithName:slotPBid];
#endif
        OpenUDIDLog(@"SlotPB name = %@",slotPBid);
        if (slotPB==nil) {
            // assign availableSlotPBid to be the first one available
            //将availableSlotPBid指定为第一个可用的
            
            if (availableSlotPBid==nil) availableSlotPBid = slotPBid;
        } else {
            NSDictionary* dict = [OpenUDID _getDictFromPasteboard:slotPB];
            NSString* oudid = [dict objectForKey:kOpenUDIDKey];
            OpenUDIDLog(@"SlotPB dict = %@",dict);
            if (oudid==nil) {
                //availableSlotPBid可以位于未找到oudid的非空插槽中
                
                // availableSlotPBid could inside a non null slot where no oudid can be found
                if (availableSlotPBid==nil) availableSlotPBid = slotPBid;
            } else {
                // increment the frequency of this oudid key
//                增加此oudo键的频率
                int count = [[frequencyDict valueForKey:oudid] intValue];
                [frequencyDict setObject:[NSNumber numberWithInt:++count] forKey:oudid];
            }
            // if we have a match with the app unique id,
            // then let's look if the external UIPasteboard representation marks this app as OptedOut
            //如果我们与应用程序唯一id匹配,
            
            //然后让我们看看外部UIPasteboard表示是否将此应用程序标记为opendout
            NSString* gid = [dict objectForKey:kOpenUDIDAppUIDKey];
            if (gid!=nil && [gid isEqualToString:appUID]) {
                myRedundancySlotPBid = slotPBid;
                //本地词典在选择退出主题上是首选项,因此如果已经在本地选择退出,请忽略
                // the local dictionary is prime on the opt-out subject, so ignore if already opted-out locally
                if (optedOut) {
                    optedOutDate = [dict objectForKey:kOpenUDIDOOTSKey];
                    optedOut = optedOutDate!=nil;   
                }
            }
        }
    }
    //对同一OpenUDID(冗余、故障保护)中出现次数最高的频率dict进行排序
    //最高的是最后一个
    // sort the Frequency dict with highest occurence count of the same OpenUDID (redundancy, failsafe)
    // highest is last in the list
    //
    NSArray* arrayOfUDIDs = [frequencyDict keysSortedByValueUsingSelector:@selector(compare:)];
    NSString* mostReliableOpenUDID = (arrayOfUDIDs!=nil && [arrayOfUDIDs count]>0)? [arrayOfUDIDs lastObject] : nil;
    OpenUDIDLog(@"Freq Dict = %@\nMost reliable %@",frequencyDict,mostReliableOpenUDID);
        
    // if openUDID was not retrieved from the local preferences, then let's try to get it from the frequency dictionary above
    //
    //如果没有从本地首选项中检索到openUDID,那么让我们尝试从上面的频率字典中获取它
    if (openUDID==nil) {        
        if (mostReliableOpenUDID==nil) {
            // this is the case where this app instance is likely to be the first one to use OpenUDID on this device
            // we create the OpenUDID, legacy or semi-random (i.e. most certainly unique)
            //
            //在这种情况下,此应用程序实例可能是第一个在此设备上使用OpenUDID的应用程序实例
            
            //我们创建OpenUDID、legacy或半随机(也就是说,非常独特)
            
            //
            openUDID = [OpenUDID _generateFreshOpenUDID];
        } else {
            // or we leverage the OpenUDID shared by other apps that have already gone through the process
            //
            //或者我们利用其他已经完成这个过程的应用程序共享的OpenUDID
            openUDID = mostReliableOpenUDID;
        }
        // then we create a local representation
        //
        
        
        //然后我们创建一个局部表示
        if (localDict==nil) { 
            localDict = [NSMutableDictionary dictionaryWithCapacity:4];
            [localDict setObject:openUDID forKey:kOpenUDIDKey];
            [localDict setObject:appUID forKey:kOpenUDIDAppUIDKey];
            [localDict setObject:[NSDate date] forKey:kOpenUDIDTSKey];
            if (optedOut) [localDict setObject:optedOutDate forKey:kOpenUDIDTSKey];
            saveLocalDictToDefaults = YES;
        }
    }
    else {
        // Sanity/tampering check
        ////健全/篡改检查
        if (mostReliableOpenUDID!=nil && ![mostReliableOpenUDID isEqualToString:openUDID])
            isCompromised = YES;
    }
    
    // Here we store in the available PB slot, if applicable
    ////如果适用,我们将存储在可用的PB插槽中
    

    OpenUDIDLog(@"Available Slot %@ Existing Slot %@",availableSlotPBid,myRedundancySlotPBid);
    if (availableSlotPBid!=nil && (myRedundancySlotPBid==nil || [availableSlotPBid isEqualToString:myRedundancySlotPBid])) {
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
        UIPasteboard* slotPB = [UIPasteboard pasteboardWithName:availableSlotPBid create:YES];
        [slotPB setPersistent:YES];
#else
        NSPasteboard* slotPB = [NSPasteboard pasteboardWithName:availableSlotPBid];
#endif
        
        // save slotPBid to the defaults, and remember to save later
        ////将slotPBid保存为默认值,并记住以后保存
        

        if (localDict) {
            [localDict setObject:availableSlotPBid forKey:kOpenUDIDSlotKey];
            saveLocalDictToDefaults = YES;
        }
        
        // Save the local dictionary to the corresponding UIPasteboard slot
        ////将本地字典保存到相应的UIPasteboard插槽
        

        if (openUDID && localDict)
            [OpenUDID _setDict:localDict forPasteboard:slotPB];
    }

    // Save the dictionary locally if applicable
    ////在本地保存字典(如果适用)
    

    if (localDict && saveLocalDictToDefaults)
        [defaults setObject:localDict forKey:kOpenUDIDKey];

    // If the UIPasteboard external representation marks this app as opted-out, then to respect privacy, we return the ZERO OpenUDID, a sequence of 40 zeros...
    // This is a *new* case that developers have to deal with. Unlikely, statistically low, but still.
    // To circumvent this and maintain good tracking (conversion ratios, etc.), developers are invited to calculate how many of their users have opted-out from the full set of users.
    // This ratio will let them extrapolate convertion ratios more accurately.
    //
    //如果UIPasteboard外部表示将此应用程序标记为已选择退出,那么为了尊重隐私,我们将返回零OpenUDID,一个40个零的序列。。。
    
    //这是一个开发人员必须处理的“新”案例。不太可能,统计数据很低,但仍然如此。
    
    //为了避免这种情况,并保持良好的跟踪(转换率等),请开发人员计算出有多少用户从完整的用户集中选择出来。
    
    //这个比率将使他们能够更准确地推断转换比率。
    
    //
    if (optedOut) {
        if (error!=nil) *error = [NSError errorWithDomain:kOpenUDIDDomain
                                                     code:kOpenUDIDErrorOptedOut
                                                 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Application with unique id %@ is opted-out from OpenUDID as of %@",appUID,optedOutDate],@"description", nil]];
            
        kOpenUDIDSessionCache = [[NSString stringWithFormat:@"%040x",0] retain];
        return kOpenUDIDSessionCache;
    }

    // return the well earned openUDID!
    //把赚得盆满钵满的openUDID还给我!
    

    if (error!=nil) {
        if (isCompromised)
            *error = [NSError errorWithDomain:kOpenUDIDDomain
                                         code:kOpenUDIDErrorCompromised
                                     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Found a discrepancy between stored OpenUDID (reliable) and redundant copies; one of the apps on the device is most likely corrupting the OpenUDID protocol",@"description", nil]];
        else
            *error = [NSError errorWithDomain:kOpenUDIDDomain
                                         code:kOpenUDIDErrorNone
                                     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID succesfully retrieved",@"description", nil]];
    }
    kOpenUDIDSessionCache = [openUDID retain];
    return kOpenUDIDSessionCache;
}

将其添加到工程使用hopper反编译的伪源码是

void * +[OpenUDID _generateFreshOpenUDID](void * self, void * _cmd) {
    var_58 = 0x0;
    if (var_58 == 0x0) {
            var_60 = CFUUIDCreate(*_kCFAllocatorDefault);
            var_68 = CFUUIDCreateString(*_kCFAllocatorDefault, var_60);
            rax = CFStringGetFastestEncoding(var_68);
            rax = CFStringGetCStringPtr(var_68, rax);
            CC_MD5(rax, strlen(rax), &var_40);
            CFRelease(var_60);
            CFRelease(var_68);
            var_58 = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%08x", var_40 & 0xff, var_3F & 0xff, var_3E & 0xff, var_3D & 0xff, var_3C & 0xff, var_3B & 0xff, var_3A & 0xff, var_39 & 0xff, var_38 & 0xff, var_37 & 0xff, var_36 & 0xff, var_35 & 0xff, var_34 & 0xff, var_33 & 0xff, var_32 & 0xff, var_31 & 0xff, arc4random() % 0xffffffffffffffff];
    }
    var_100 = var_58;
    if (*___stack_chk_guard == *___stack_chk_guard) {
            rax = var_100;
    }
    else {
            rax = __stack_chk_fail();
    }
    return rax;
}

void * +[OpenUDID valueWithError:](void * self, void * _cmd, void * * arg2) {
    var_20 = arg2;
    if (*_kOpenUDIDSessionCache != 0x0) {
            if (var_20 != 0x0) {
                    *var_20 = [NSError errorWithDomain:@"org.OpenUDID" code:0x0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID in cache from first call", @"description", 0x0]];
            }
            var_8 = *_kOpenUDIDSessionCache;
    }
    else {
            var_28 = [NSUserDefaults standardUserDefaults];
            var_30 = [var_28 objectForKey:@"OpenUDID_appUID"];
            if (var_30 == 0x0) {
                    var_38 = CFUUIDCreate(0x0);
                    var_30 = CFUUIDCreateString(0x0, var_38);
                    CFRelease(var_38);
                    [var_30 autorelease];
            }
            var_40 = 0x0;
            var_48 = 0x0;
            var_50 = 0x0;
            var_51 = 0x0;
            var_52 = 0x0;
            var_53 = 0x0;
            var_60 = [var_28 objectForKey:@"OpenUDID"];
            if (([var_60 isKindOfClass:[NSDictionary class]] & 0x1) != 0x0) {
                    var_60 = [NSMutableDictionary dictionaryWithDictionary:var_60];
                    var_40 = [var_60 objectForKey:@"OpenUDID"];
                    var_48 = [var_60 objectForKey:@"OpenUDID_slot"];
                    var_50 = [var_60 objectForKey:@"OpenUDID_optOutTS"];
                    var_51 = (var_50 != 0x0 ? 0x1 : 0x0) & 0x1;
            }
            var_68 = 0x0;
            var_70 = [NSMutableDictionary dictionaryWithCapacity:0x64];
            for (var_74 = 0x0; var_74 < 0x64; var_74 = var_74 + 0x1) {
                    var_80 = [NSString stringWithFormat:@"%@%d", @"org.OpenUDID.slot.", var_74];
                    var_88 = [UIPasteboard pasteboardWithName:var_80 create:0x0];
                    if (var_88 == 0x0) {
                            if (var_68 == 0x0) {
                                    var_68 = var_80;
                            }
                    }
                    else {
                            var_90 = [OpenUDID _getDictFromPasteboard:var_88];
                            var_98 = [var_90 objectForKey:@"OpenUDID"];
                            if (var_98 == 0x0) {
                                    if (var_68 == 0x0) {
                                            var_68 = var_80;
                                    }
                            }
                            else {
                                    [var_70 setObject:[NSNumber numberWithInt:[[var_70 valueForKey:var_98] intValue] + 0x1] forKey:var_98];
                            }
                            var_A8 = [var_90 objectForKey:@"OpenUDID_appUID"];
                            if ((var_A8 != 0x0) && (([var_A8 isEqualToString:var_30] & 0x1) != 0x0)) {
                                    var_48 = var_80;
                                    if ((var_51 & 0x1) != 0x0) {
                                            var_50 = [var_90 objectForKey:@"OpenUDID_optOutTS"];
                                            var_51 = (var_50 != 0x0 ? 0x1 : 0x0) & 0x1;
                                    }
                            }
                    }
            }
            var_B0 = [var_70 keysSortedByValueUsingSelector:@selector(compare:)];
            if ((var_B0 != 0x0) && ([var_B0 count] > 0x0)) {
                    var_118 = [var_B0 lastObject];
            }
            else {
                    var_118 = 0x0;
            }
            var_B8 = var_118;
            if (var_40 == 0x0) {
                    if (var_B8 == 0x0) {
                            var_40 = [OpenUDID _generateFreshOpenUDID];
                    }
                    else {
                            var_40 = var_B8;
                    }
                    if (var_60 == 0x0) {
                            var_60 = [NSMutableDictionary dictionaryWithCapacity:0x4];
                            [var_60 setObject:var_40 forKey:@"OpenUDID"];
                            [var_60 setObject:var_30 forKey:@"OpenUDID_appUID"];
                            [var_60 setObject:[NSDate date] forKey:@"OpenUDID_createdTS"];
                            if ((var_51 & 0x1) != 0x0) {
                                    [var_60 setObject:var_50 forKey:@"OpenUDID_createdTS"];
                            }
                            var_52 = 0x1;
                    }
            }
            else {
                    if ((var_B8 != 0x0) && (([var_B8 isEqualToString:var_40] & 0x1) == 0x0)) {
                            var_53 = 0x1;
                    }
            }
            if ((var_68 != 0x0) && (((var_48 == 0x0) || (([var_68 isEqualToString:var_48] & 0x1) != 0x0)))) {
                    var_C0 = [UIPasteboard pasteboardWithName:var_68 create:0x1];
                    [var_C0 setPersistent:0x1];
                    if (var_60 != 0x0) {
                            [var_60 setObject:var_68 forKey:@"OpenUDID_slot"];
                            var_52 = 0x1;
                    }
                    if ((var_40 != 0x0) && (var_60 != 0x0)) {
                            [OpenUDID _setDict:var_60 forPasteboard:var_C0];
                    }
            }
            if ((var_60 != 0x0) && ((var_52 & 0x1) != 0x0)) {
                    [var_28 setObject:var_60 forKey:@"OpenUDID"];
            }
            if ((var_51 & 0x1) != 0x0) {
                    if (var_20 != 0x0) {
                            *var_20 = [NSError errorWithDomain:@"org.OpenUDID" code:0x1 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Application with unique id %@ is opted-out from OpenUDID as of %@", var_30, var_50], @"description", 0x0]];
                    }
                    *_kOpenUDIDSessionCache = [[NSString stringWithFormat:@"%040x", 0x0] retain];
                    var_8 = *_kOpenUDIDSessionCache;
            }
            else {
                    if (var_20 != 0x0) {
                            if ((var_53 & 0x1) != 0x0) {
                                    *var_20 = [NSError errorWithDomain:@"org.OpenUDID" code:0x2 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Found a discrepancy between stored OpenUDID (reliable) and redundant copies; one of the apps on the device is most likely corrupting the OpenUDID protocol", @"description", 0x0]];
                            }
                            else {
                                    *var_20 = [NSError errorWithDomain:@"org.OpenUDID" code:0x0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID succesfully retrieved", @"description", 0x0]];
                            }
                    }
                    *_kOpenUDIDSessionCache = [var_40 retain];
                    var_8 = *_kOpenUDIDSessionCache;
            }
    }
    rax = var_8;
    return rax;
}

这个在2013年作者就deprecated了。

我的运行环境:xcode10 ,ios12.1

疑问1:kOpenUDIDAppUIDKey  = @"OpenUDID_appUID"  ,注释是:在pastebins中唯一标识此应用程序,但是它直接取值NSUserDefaults的一级,但没地方存!!每次运行都是空值,它是怎么判断的?320多行创建的  390多行才使用

疑问2:本地副本意思是NSUserDefaults存 kOpenUDIDKey = @"OpenUDID"的key对应的字典里面也有一个

疑问3:然后进入循环,kOpenUDIDRedundancySlots = 100  ,100遍,只有第一遍有值,其他99遍都啥都没赋值,也不知道有啥用,

kOpenUDIDSlotPBPrefix = @"org.OpenUDID.slot."这个标记了循环的顺序。

疑问4:从剪贴板获取[UIPasteboard pasteboardWithName:slotPBid(org.OpenUDID.slot.0) create:NO],的值是

{

    OpenUDID = 02f268b1add131a529845a3a1886b8c6df279e89;//uuidcreate后做md5

    "OpenUDID_appUID" = "C3FD02F2-FA71-4732-A674-DEB1DF338FE6";、//系统uuidcreate创建

    "OpenUDID_createdTS" = "2020-03-02 13:18:01 +0000";时间

    "OpenUDID_slot" = "org.OpenUDID.slot.0";创建顺序

}这个是卸载重装也会有的

剪贴板的key是org.OpenUDID.slot.0类似

上面这个字典NSUserDefaults也存一遍,key是kOpenUDIDKey = @"OpenUDID"

系统还原后看循环:循环里面一个都不走,然后通过[OpenUDID _generateFreshOpenUDID]创建第一个值,重新走一遍这个方法CFUUIDCreateString md5,作为openudid, 然后320行那里的创建的作为kOpenUDIDAppUIDKey,

存剪贴板 本地

{

    OpenUDID = 958a60666597945dabf734d1e8767bbcb7d68708;

    "OpenUDID_appUID" = "053E23DB-D3A0-42B0-B640-FF5EA911B9DA";

    "OpenUDID_createdTS" = "2020-03-03 03:19:16 +0000";

    "OpenUDID_slot" = "org.OpenUDID.slot.0";

}

完成

以下是+[UTDevice utdid]如何实现的一些探索

void * +[UTDevice utdid](void * self, void * _cmd) {
    var_-96 = 0x0;
    var_-88 = &var_-96;
    var_-176 = &var_-56;
    var_-184 = [UTDIDOpenUDID value];
    *var_-176 = [var_-184 retain];
    var_-192 = &var_-96 + 0x28;
    objc_storeStrong(&var_-16, &var_-152);
    if (*_utdid.onceToken != 0xffffffffffffffff) {
            dispatch_once(_utdid.onceToken, 0x0);
    }
    var_-16 = 0x0;
    objc_storeStrong(&var_-16, 0x0);
    if (*(var_-88 + 0x28) == 0x0) {
            var_-200 = @"ffffffffffffffffffffffff";
    }
    else {
            var_-200 = *(var_-88 + 0x28);
    }
    var_-24 = [var_-200 retain];
    _Block_object_dispose(&var_-96, 0x8);
    rdi = var_-192;
    objc_storeStrong(rdi, 0x0);
    var_-212 = 0x1;
    if ((0x0 & 0x1) == 0x0) {
            rcx = var_-212 - 0x2;
            var_-216 = var_-212;
            if (rcx != 0x0) {
                    rax = var_-216 - 0x3;
                    if (rax != 0x0) {
                            rax = [var_-24 autorelease];
                    }
                    else {
                            *(rdi + 0x28) = 0x0;
                            objc_storeStrong(rdi + 0x28, *0x28);
                            rax = objc_storeStrong(0x28, 0x0);
                    }
            }
            else {
                    var_-24 = [@"eeeeeeeeeeeeeeeeeeeeeeee" retain];
                    rax = [var_-24 autorelease];
            }
    }
    else {
            rax = objc_exception_rethrow();
    }
    return rax;
}

这么一堆就一句有用 [UTDIDOpenUDID value];

void * +[UTDIDOpenUDID value](void * self, void * _cmd) {
    rax = [UTDIDOpenUDID valueWithError:0x0];
    return rax;
}

下一个方法

void * +[UTDIDOpenUDID valueWithError:](void * self, void * _cmd, void * * arg2) {
    var_-16 = self;
    var_-32 = arg2;
    if (*_kUTDIDOpenUDIDSessionCache != 0x0) {
            if (var_-32 != 0x0) {
                    *var_-32 = [NSError errorWithDomain:@"com.UTDID" code:0x0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID in cache from first call", @"description", 0x0]];
            }
            var_-8 = *_kUTDIDOpenUDIDSessionCache;
    }
    else {
            var_-40 = [NSUserDefaults standardUserDefaults];
            var_-48 = 0x0;
            var_-56 = 0x0;
            var_-64 = 0x0;
            var_-65 = 0x0;
            var_-66 = 0x0;
            var_-67 = 0x0;
            var_-80 = [var_-40 objectForKey:@"UTDID"];
            if (([var_-80 isKindOfClass:[NSDictionary class]] & 0x1) == 0x0) {
                    var_-88 = 0x0;
                    var_-96 = [NSMutableDictionary dictionaryWithCapacity:0x64];
                    var_-104 = [var_-16 appUid];
                    for (var_-108 = 0x0; var_-108 < 0x64; var_-108 = var_-108 + 0x1) {
                            var_-248 = [NSString stringWithFormat:@"%@%d", @"com.UTDID.", var_-108];
                            var_-120 = var_-248;
                            var_-272 = [UIPasteboard pasteboardWithName:var_-248 create:0x0];
                            var_-144 = var_-272;
                            if (var_-144 == 0x0) {
                                    if (var_-88 == 0x0) {
                                            var_-88 = var_-120;
                                    }
                            }
                            else {
                                    var_-280 = [UTDIDOpenUDID _getDictFromPasteboard:var_-144];
                                    var_-152 = var_-280;
                                    var_-288 = [var_-280 objectForKey:@"UTDID"];
                                    var_-160 = var_-288;
                                    if (var_-160 == 0x0) {
                                            if (var_-88 == 0x0) {
                                                    var_-88 = var_-120;
                                            }
                                    }
                                    else {
                                            var_-296 = [var_-96 valueForKey:var_-160];
                                            var_-300 = [var_-296 intValue];
                                            var_-312 = var_-96;
                                            var_-328 = [NSNumber numberWithInt:var_-300 + 0x1];
                                            [var_-312 setObject:var_-328 forKey:var_-160];
                                    }
                                    var_-336 = [var_-152 objectForKey:@"UTDID_appUID"];
                                    var_-176 = var_-336;
                                    if (var_-176 != 0x0) {
                                            var_-337 = [var_-176 isEqualToString:var_-104];
                                            if ((var_-337 & 0x1) != 0x0) {
                                                    var_-56 = var_-120;
                                                    if ((var_-65 & 0x1) != 0x0) {
                                                            var_-352 = [var_-152 objectForKey:@"UTDID_optOutTS"];
                                                            var_-64 = var_-352;
                                                            var_-65 = (var_-64 != 0x0 ? 0x1 : 0x0) & 0x1;
                                                    }
                                            }
                                    }
                            }
                    }
                    var_-192 = [var_-96 keysSortedByValueUsingSelector:@selector(compare:)];
                    if ((var_-192 != 0x0) && ([var_-192 count] > 0x0)) {
                            var_-360 = [var_-192 lastObject];
                    }
                    else {
                            var_-360 = 0x0;
                    }
                    var_-200 = var_-360;
                    if (var_-48 == 0x0) {
                            if (var_-200 == 0x0) {
                                    var_-48 = [[[UTDIDMain alloc] init] value];
                            }
                            else {
                                    var_-48 = var_-200;
                            }
                            if (var_-80 == 0x0) {
                                    var_-80 = [NSMutableDictionary dictionaryWithCapacity:0x4];
                                    [var_-80 setObject:var_-48 forKey:@"UTDID"];
                                    [var_-80 setObject:var_-104 forKey:@"UTDID_appUID"];
                                    [var_-80 setObject:[NSDate date] forKey:@"UTDID_createdTS"];
                                    if ((var_-65 & 0x1) != 0x0) {
                                            [var_-80 setObject:var_-64 forKey:@"UTDID_createdTS"];
                                    }
                                    var_-66 = 0x1;
                            }
                    }
                    else {
                            if ((var_-200 != 0x0) && (([var_-200 isEqualToString:var_-48] & 0x1) == 0x0)) {
                                    var_-67 = 0x1;
                            }
                    }
                    if ((var_-88 != 0x0) && (((var_-56 == 0x0) || (([var_-88 isEqualToString:var_-56] & 0x1) != 0x0)))) {
                            var_-208 = [UIPasteboard pasteboardWithName:var_-88 create:0x1];
                            [var_-208 setPersistent:0x1];
                            if (var_-80 != 0x0) {
                                    [var_-80 setObject:var_-88 forKey:@"UTDID_slot"];
                                    var_-66 = 0x1;
                            }
                            if ((var_-48 != 0x0) && (var_-80 != 0x0)) {
                                    [UTDIDOpenUDID _setDict:var_-80 forPasteboard:var_-208];
                            }
                    }
                    if ((var_-80 != 0x0) && ((var_-66 & 0x1) != 0x0)) {
                            [var_-40 setObject:var_-80 forKey:@"UTDID"];
                    }
                    if ((var_-65 & 0x1) != 0x0) {
                            if (var_-32 != 0x0) {
                                    *var_-32 = [NSError errorWithDomain:@"com.UTDID" code:0x1 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Application with unique id %@ is opted-out from OpenUDID as of %@", var_-104, var_-64], @"description", 0x0]];
                            }
                            *_kUTDIDOpenUDIDSessionCache = [[NSString stringWithFormat:@"%040x", 0x0] retain];
                            var_-8 = *_kUTDIDOpenUDIDSessionCache;
                    }
                    else {
                            if (var_-32 != 0x0) {
                                    if ((var_-67 & 0x1) != 0x0) {
                                            *var_-32 = [NSError errorWithDomain:@"com.UTDID" code:0x2 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Found a discrepancy between stored OpenUDID (reliable) and redundant copies; one of the apps on the device is most likely corrupting the OpenUDID protocol", @"description", 0x0]];
                                    }
                                    else {
                                            *var_-32 = [NSError errorWithDomain:@"com.UTDID" code:0x0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID succesfully retrieved", @"description", 0x0]];
                                    }
                            }
                            *_kUTDIDOpenUDIDSessionCache = [var_-48 retain];
                            var_-8 = *_kUTDIDOpenUDIDSessionCache;
                    }
            }
            else {
                    var_-80 = [NSMutableDictionary dictionaryWithDictionary:var_-80];
                    var_-48 = [var_-80 objectForKey:@"UTDID"];
                    var_-56 = [var_-80 objectForKey:@"UTDID_slot"];
                    var_-64 = [var_-80 objectForKey:@"UTDID_optOutTS"];
                    var_-65 = (var_-64 != 0x0 ? 0x1 : 0x0) & 0x1;
                    if (0x0 != var_-48) {
                            *_kUTDIDOpenUDIDSessionCache = [var_-48 retain];
                            var_-8 = *_kUTDIDOpenUDIDSessionCache;
                    }
                    else {
                            var_-88 = 0x0;
                            var_-96 = [NSMutableDictionary dictionaryWithCapacity:0x64];
                            var_-104 = [var_-16 appUid];
                            for (var_-108 = 0x0; var_-108 < 0x64; var_-108 = var_-108 + 0x1) {
                                    var_-248 = [NSString stringWithFormat:@"%@%d", @"com.UTDID.", var_-108];
                                    var_-120 = var_-248;
                                    var_-272 = [UIPasteboard pasteboardWithName:var_-248 create:0x0];
                                    var_-144 = var_-272;
                                    if (var_-144 == 0x0) {
                                            if (var_-88 == 0x0) {
                                                    var_-88 = var_-120;
                                            }
                                    }
                                    else {
                                            var_-280 = [UTDIDOpenUDID _getDictFromPasteboard:var_-144];
                                            var_-152 = var_-280;
                                            var_-288 = [var_-280 objectForKey:@"UTDID"];
                                            var_-160 = var_-288;
                                            if (var_-160 == 0x0) {
                                                    if (var_-88 == 0x0) {
                                                            var_-88 = var_-120;
                                                    }
                                            }
                                            else {
                                                    var_-296 = [var_-96 valueForKey:var_-160];
                                                    var_-300 = [var_-296 intValue];
                                                    var_-312 = var_-96;
                                                    var_-328 = [NSNumber numberWithInt:var_-300 + 0x1];
                                                    [var_-312 setObject:var_-328 forKey:var_-160];
                                            }
                                            var_-336 = [var_-152 objectForKey:@"UTDID_appUID"];
                                            var_-176 = var_-336;
                                            if (var_-176 != 0x0) {
                                                    var_-337 = [var_-176 isEqualToString:var_-104];
                                                    if ((var_-337 & 0x1) != 0x0) {
                                                            var_-56 = var_-120;
                                                            if ((var_-65 & 0x1) != 0x0) {
                                                                    var_-352 = [var_-152 objectForKey:@"UTDID_optOutTS"];
                                                                    var_-64 = var_-352;
                                                                    var_-65 = (var_-64 != 0x0 ? 0x1 : 0x0) & 0x1;
                                                            }
                                                    }
                                            }
                                    }
                            }
                            var_-192 = [var_-96 keysSortedByValueUsingSelector:@selector(compare:)];
                            if ((var_-192 != 0x0) && ([var_-192 count] > 0x0)) {
                                    var_-360 = [var_-192 lastObject];
                            }
                            else {
                                    var_-360 = 0x0;
                            }
                            var_-200 = var_-360;
                            if (var_-48 == 0x0) {
                                    if (var_-200 == 0x0) {
                                            var_-48 = [[[UTDIDMain alloc] init] value];
                                    }
                                    else {
                                            var_-48 = var_-200;
                                    }
                                    if (var_-80 == 0x0) {
                                            var_-80 = [NSMutableDictionary dictionaryWithCapacity:0x4];
                                            [var_-80 setObject:var_-48 forKey:@"UTDID"];
                                            [var_-80 setObject:var_-104 forKey:@"UTDID_appUID"];
                                            [var_-80 setObject:[NSDate date] forKey:@"UTDID_createdTS"];
                                            if ((var_-65 & 0x1) != 0x0) {
                                                    [var_-80 setObject:var_-64 forKey:@"UTDID_createdTS"];
                                            }
                                            var_-66 = 0x1;
                                    }
                            }
                            else {
                                    if ((var_-200 != 0x0) && (([var_-200 isEqualToString:var_-48] & 0x1) == 0x0)) {
                                            var_-67 = 0x1;
                                    }
                            }
                            if ((var_-88 != 0x0) && (((var_-56 == 0x0) || (([var_-88 isEqualToString:var_-56] & 0x1) != 0x0)))) {
                                    var_-208 = [UIPasteboard pasteboardWithName:var_-88 create:0x1];
                                    [var_-208 setPersistent:0x1];
                                    if (var_-80 != 0x0) {
                                            [var_-80 setObject:var_-88 forKey:@"UTDID_slot"];
                                            var_-66 = 0x1;
                                    }
                                    if ((var_-48 != 0x0) && (var_-80 != 0x0)) {
                                            [UTDIDOpenUDID _setDict:var_-80 forPasteboard:var_-208];
                                    }
                            }
                            if ((var_-80 != 0x0) && ((var_-66 & 0x1) != 0x0)) {
                                    [var_-40 setObject:var_-80 forKey:@"UTDID"];
                            }
                            if ((var_-65 & 0x1) != 0x0) {
                                    if (var_-32 != 0x0) {
                                            *var_-32 = [NSError errorWithDomain:@"com.UTDID" code:0x1 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"Application with unique id %@ is opted-out from OpenUDID as of %@", var_-104, var_-64], @"description", 0x0]];
                                    }
                                    *_kUTDIDOpenUDIDSessionCache = [[NSString stringWithFormat:@"%040x", 0x0] retain];
                                    var_-8 = *_kUTDIDOpenUDIDSessionCache;
                            }
                            else {
                                    if (var_-32 != 0x0) {
                                            if ((var_-67 & 0x1) != 0x0) {
                                                    *var_-32 = [NSError errorWithDomain:@"com.UTDID" code:0x2 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Found a discrepancy between stored OpenUDID (reliable) and redundant copies; one of the apps on the device is most likely corrupting the OpenUDID protocol", @"description", 0x0]];
                                            }
                                            else {
                                                    *var_-32 = [NSError errorWithDomain:@"com.UTDID" code:0x0 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"OpenUDID succesfully retrieved", @"description", 0x0]];
                                            }
                                    }
                                    *_kUTDIDOpenUDIDSessionCache = [var_-48 retain];
                                    var_-8 = *_kUTDIDOpenUDIDSessionCache;
                            }
                    }
            }
    }
    rax = var_-8;
    return rax;
}

1 & 0x1   = 1;

不是字典时

void * +[UTDIDOpenUDID appUid](void * self, void * _cmd) {
    var_20 = [[NSUserDefaults standardUserDefaults] objectForKey:@"UTDID_appUID"];
    if (var_20 == 0x0) {
            var_28 = CFUUIDCreate(0x0);
            var_20 = CFUUIDCreateString(0x0, var_28);
            CFRelease(var_28);
            [var_20 autorelease];
    }
    rax = var_20;
    return rax;
}

function CFUUIDCreate {
    rax = _CFUUIDCreate(rdi);
    return rax;
}

function CFUUIDCreateString {
    rax = _CFUUIDCreateString(rdi, rsi);
    return rax;
}

上面这是系统提供的生成uuid的c语言方法

[UIPasteboard pasteboardWithName:var_F8 create:0x0]; 这也是系统方法

void * +[UTDIDOpenUDID _getDictFromPasteboard:](void * self, void * _cmd, void * arg2) {
    var_20 = [arg2 dataForPasteboardType:@"com.UTDID"];
    if (var_20 != 0x0) {
            var_40 = [NSKeyedUnarchiver unarchiveObjectWithData:var_20];
            var_20 = var_40;
    }
    if ((var_20 != 0x0) && (([var_20 isKindOfClass:[NSDictionary class]] & 0x1) == 0x0)) {
            var_58 = 0x0;
    }
    else {
            var_58 = var_20;
    }
    rax = [NSMutableDictionary dictionaryWithDictionary:var_58];
    return rax;
}

把上面代码循环64遍后,然后又出来下面的一个方法 

void * -[UTDIDMain value](void * self, void * _cmd) {
    var_10 = self;
    rax = [@"S_UTDID_OPT_LOCK" retain];
    var_98 = rax;
    objc_sync_enter(rax);
    if (0x0 == *_s_utdid) goto loc_100e18800;

loc_100e187e1:
    var_8 = [*_s_utdid retain];
    goto loc_100e18d83;

loc_100e18d83:
    objc_sync_exit(var_98);
    [var_98 release];
    rax = [var_8 autorelease];
    return rax;

loc_100e18800:
    [var_10 preInit];
    var_2D = 0x1;
    var_2E = 0x0;
    var_A8 = [NSUserDefaults standardUserDefaults];
    rax = [var_A8 retain];
    var_38 = rax;
    var_B8 = [rax objectForKey:@"PK_455469921"];
    var_40 = [var_B8 retain];
    var_49 = 0x0;
    var_B9 = 0x1;
    if (0x0 != var_40) {
            var_C8 = [var_10->mUtdidHelper dePack:var_40];
            rax = [var_C8 retain];
            var_48 = rax;
            var_49 = 0x1;
            var_B9 = 0x0 == rax ? 0x1 : 0x0;
    }
    var_C9 = var_B9;
    if ((var_49 & 0x1) != 0x0) {
            [var_48 release];
    }
    if ((var_C9 & 0x1) != 0x0) goto loc_100e1892a;

loc_100e18be6:
    var_88 = 0x0;
    var_130 = [var_10->mUtdidHelper dePack:var_40];
    var_90 = [var_130 retain];
    if (0x0 == var_90) {
            var_8 = [@"dddddddddddddddddddddddd" retain];
    }
    else {
            if ((var_2E & 0x1) != 0x0) {
                    [var_10->mDevicePersistentConfig setObject:var_40 forKey:@"c"];
                    [var_10->mDevicePersistentConfig commit];
            }
            var_138 = [UTDIDTypeConvert NSData2Base64:var_90];
            var_88 = [var_138 retain];
            [0x0 release];
            objc_storeStrong(_s_utdid, var_88);
            var_8 = [var_88 retain];
    }
    objc_storeStrong(&var_90, 0x0);
    objc_storeStrong(&var_88, 0x0);
    goto loc_100e18d63;

loc_100e18d63:
    objc_storeStrong(&var_40, 0x0);
    objc_storeStrong(&var_38, 0x0);
    goto loc_100e18d83;

loc_100e1892a:
    var_D8 = [var_10->mDevicePersistentConfig objectForKey:@"c"];
    rax = [var_D8 retain];
    rdi = var_40;
    var_40 = rax;
    [rdi release];
    var_59 = 0x0;
    var_D9 = 0x1;
    if (0x0 != var_40) {
            var_E8 = [var_10->mUtdidHelper dePack:var_40];
            rax = [var_E8 retain];
            var_58 = rax;
            var_59 = 0x1;
            var_D9 = 0x0 == rax ? 0x1 : 0x0;
    }
    var_E9 = var_D9;
    if ((var_59 & 0x1) != 0x0) {
            [var_58 release];
    }
    if ((var_E9 & 0x1) != 0x0) goto loc_100e18a0d;

loc_100e18bcc:
    var_2D = 0x0;
    goto loc_100e18be6;

loc_100e18a0d:
    var_2E = 0x1;
    var_F8 = [var_10->mUIPasteBoard dataForPasteboardType:@"K_1427156438"];
    rax = [var_F8 retain];
    rdi = var_40;
    var_40 = rax;
    [rdi release];
    var_69 = 0x0;
    var_F9 = 0x1;
    if (0x0 != var_40) {
            var_108 = [var_10->mUtdidHelper dePack:var_40];
            rax = [var_108 retain];
            var_68 = rax;
            var_69 = 0x1;
            var_F9 = 0x0 == rax ? 0x1 : 0x0;
    }
    var_109 = var_F9;
    if ((var_69 & 0x1) != 0x0) {
            [var_68 release];
    }
    if ((var_109 & 0x1) != 0x0) goto loc_100e18af7;

loc_100e18bc6:
    var_2D = 0x0;
    goto loc_100e18be6;

loc_100e18af7:
    var_118 = [var_10 generateUtdidAndSave];
    rax = [var_118 retain];
    var_78 = rax;
    var_120 = [UTDIDTypeConvert NSData2Base64:rax];
    var_80 = [var_120 retain];
    objc_storeStrong(_s_utdid, var_80);
    var_8 = [var_80 retain];
    objc_storeStrong(&var_80, 0x0);
    objc_storeStrong(&var_78, 0x0);
    goto loc_100e18d63;
}
void -[UTDIDMain preInit](void * self, void * _cmd) {
    var_-8 = self;
    if (0x0 == var_-8->mUIPasteBoard) {
            var_-8->mDevicePersistentConfig = [[UTDIDPersistentConf initWithIdentifier:@"Alvin"] retain];
            [var_-8->mDevicePersistentConfig release];
            var_-8->mUIPasteBoard = [[UIPasteboard pasteboardWithName:@"D_518825059" create:0x1] retain];
            [var_-8->mUIPasteBoard release];
            [var_-8->mUIPasteBoard setPersistent:0x1];
            var_-8->mUtdidHelper = [[UTDIDHelper alloc] init];
            [var_-8->mUtdidHelper release];
    }
    return;
}
void * +[UTDIDPersistentConf initWithIdentifier:](void * self, void * _cmd, void * arg2) {
    objc_storeStrong(&var_-32, arg2);
    if (0x0 != 0x0) {
            var_-40 = [[UTDIDPersistentConf alloc] init];
            [var_-40 create:0x0];
            var_-8 = [var_-40 retain];
            objc_storeStrong(&var_-40, 0x0);
    }
    else {
            var_-8 = 0x0;
    }
    var_-32 = 0x0;
    objc_storeStrong(&var_-32, 0x0);
    rax = [var_-8 autorelease];
    return rax;
}
void -[UTDIDPersistentConf create:](void * self, void * _cmd, void * arg2) {
    rax = &var_-24;
    var_-24 = 0x0;
    objc_storeStrong(rax, arg2);
    *(int8_t *)&self->mIsModified = 0x0;
    objc_storeStrong(&self->mIdentifier, var_-24);
    self->mKeyChainWrapper = [[UTDIDKeychainItemWrapper alloc] initWithIdentifier:self->mIdentifier accessGroup:0x0];
    [self->mKeyChainWrapper release];
    self->mPersistentFile = [[UTDIDPersistentFile createWithFile:@".UTSystemConfig" and:var_-24] retain];
    [self->mPersistentFile release];
    [self initData];
    objc_storeStrong(&var_-24, 0x0);
    return;
}
void * +[UTDIDPersistentFile createWithFile:and:](void * self, void * _cmd, void * arg2, void * arg3) {
    objc_storeStrong(&var_-32, arg2);
    objc_storeStrong(&var_-40, arg3);
    if ((([UTDIDStringUtils isEmpty:0x0] & 0x1) == 0x0) && (([UTDIDStringUtils isEmpty:0x0] & 0x1) == 0x0)) {
            var_-48 = [[UTDIDPersistentFile alloc] init];
            [var_-48 create:0x0 and:0x0];
            var_-8 = [var_-48 retain];
            objc_storeStrong(&var_-48, 0x0);
    }
    else {
            var_-8 = 0x0;
    }
    var_-32 = 0x0;
    var_-40 = 0x0;
    objc_storeStrong(&var_-40, 0x0);
    objc_storeStrong(&var_-32, 0x0);
    rax = [var_-8 autorelease];
    return rax;
}

存钥匙串

void * -[UTDIDHelper init](void * self, void * _cmd) {
    var_-8 = 0x0;
    rax = [[&var_-32 super] init];
    rsi = &var_-8;
    var_-8 = rax;
    objc_storeStrong(rsi, rax);
    if (var_-8 != 0x0) {
            rax = [@"iIAjd0narA7LwEsUqYLvMIF8n5pXBlbuYLN61VA4APYahCvFrIXj7ZsDBeRfDgqViDdsWh3YUNbqoxm7pAEm6COKYnb9KimZqJdagZHulvlr6HI6OEIqkOObZfcmWjQ1KEa1jUt9AlVVtbSXuargyTdodgA6mfJQ9RATlM5ousF8Bhh3K6WgfzB47KBqjSJ6sS1lfba90OZ9HzaW0n8YKWck3mz1WX4t8cb2oC0V5LpdTi5wNLhBqFHzRnwChbYf" dataUsingEncoding:0x4];
            rax = [rax retain];
            var_-8->mAESKey = [[UTDIDTypeConvert NSData2Base64:rax] retain];
            [var_-8->mAESKey release];
            [rax release];
    }
    var_-72 = [var_-8 retain];
    objc_storeStrong(&var_-8, 0x0);
    rax = var_-72;
    return rax;
}

上面是aes的秘钥

void * -[UTDIDHelper dePack:](void * self, void * _cmd, void * arg2) {
    objc_storeStrong(&var_-128, arg2);
    var_-136 = [[UTDIDAES AES256DecryptWithKey:0x0 forKey:self->mAESKey] retain];
    if ([var_-136 length] == 0x16) {
            var_-160 = [[UTDIDBaseUtils platform] retain];
            if (0x0 != var_-160) {
                    var_-168 = [[UTDIDIntUtils bytes:[UTDIDStringUtils hashCode:var_-160]] retain];
                    var_-192 = [[var_-136 subdataWithRange:0x0] retain];
                    var_-200 = [[UTDIDIntUtils bytes:0x0] retain];
                    if ((([var_-200 isEqualToData:var_-192] & 0x1) == 0x0) && (([var_-168 isEqualToData:var_-192] & 0x1) == 0x0)) {
                            var_-104 = 0x0;
                            var_-204 = 0x1;
                    }
                    else {
                            var_-204 = 0x0;
                    }
                    objc_storeStrong(&var_-200, 0x0);
                    objc_storeStrong(&var_-192, 0x0);
                    objc_storeStrong(&var_-168, 0x0);
                    if (var_-204 == 0x0) {
                            var_-232 = [[var_-136 subdataWithRange:0x4] retain];
                            var_-104 = [var_-232 retain];
                            objc_storeStrong(&var_-232, 0x0);
                    }
            }
            else {
                    var_-232 = [[var_-136 subdataWithRange:0x4] retain];
                    var_-104 = [var_-232 retain];
                    objc_storeStrong(&var_-232, 0x0);
            }
            objc_storeStrong(&var_-160, 0x0);
    }
    else {
            var_-104 = 0x0;
    }
    var_-128 = 0x0;
    objc_storeStrong(&var_-136, 0x0);
    objc_storeStrong(&var_-128, 0x0);
    rax = [var_-104 autorelease];
    return rax;
}
void * +[UTDIDBaseUtils platform](void * self, void * _cmd) {
    sysctlbyname("hw.machine", 0x0, &var_-32, 0x0, 0x0);
    var_-40 = malloc(var_-32);
    if (var_-40 != 0x0) {
            sysctlbyname("hw.machine", var_-40, &var_-32, 0x0, 0x0);
            var_-48 = [[NSString stringWithCString:var_-40 encoding:0x4] retain];
            free(var_-40);
            var_-8 = [var_-48 retain];
            objc_storeStrong(&var_-48, 0x0);
    }
    else {
            var_-8 = 0x0;
    }
    rax = [var_-8 autorelease];
    return rax;
}
void * +[UTDIDIntUtils bytes:](void * self, void * _cmd, unsigned int arg2) {
    var_-24 = var_-17;
    rax = [NSData dataWithBytes:&var_-24 length:0x4];
    rax = [rax retain];
    var_-32 = rax;
    var_-56 = [rax retain];
    objc_storeStrong(&var_-32, 0x0);
    rax = [var_-56 autorelease];
    return rax;
}
int +[UTDIDStringUtils hashCode:](void * self, void * _cmd, void * arg2) {
    objc_storeStrong(&var_-32, arg2);
    if (0x0 == 0x0) {
            var_-4 = 0x0;
    }
    else {
            var_-40 = 0x0;
            if ((var_-40 == 0x0) && ([0x0 length] > 0x0)) {
                    var_-48 = [objc_retainAutorelease(0x0) UTF8String];
                    var_-52 = 0x0;
                    while (sign_extend_64(var_-52) < [0x0 length]) {
                            var_-40 = var_-40 * 0x1f + sign_extend_64(*(int8_t *)(var_-48 + sign_extend_64(var_-52)));
                            var_-52 = var_-52 + 0x1;
                    }
            }
            var_-4 = var_-40;
    }
    var_-32 = 0x0;
    objc_storeStrong(&var_-32, 0x0);
    rax = var_-4;
    return rax;
}
void * +[UTDIDTypeConvert NSData2Base64:](void * self, void * _cmd, void * arg2) {
    objc_storeStrong(&var_-24, arg2);
    var_-28 = 0x0;
    var_-40 = [UTDIDTypeConvert newBase64Encode:[objc_retainAutorelease(0x0) bytes] :[0x0 length] :0x1 :&var_-28];
    var_-48 = 0x0;
    if (var_-40 != 0x0) {
            if (var_-28 > 0x0) {
                    var_-48 = [[NSString alloc] initWithBytes:var_-40 length:var_-28 encoding:0x1];
                    [0x0 release];
            }
            free(var_-40);
    }
    var_-24 = 0x0;
    var_-88 = [var_-48 retain];
    objc_storeStrong(&var_-48, 0x0);
    objc_storeStrong(&var_-24, 0x0);
    rax = [var_-88 autorelease];
    return rax;
}
char * +[UTDIDTypeConvert newBase64Encode::::](void * self, void * _cmd, void * arg2, unsigned int arg3, bool arg4, unsigned int * arg5) {
    r8 = 0x0;
    var_-36 = arg3;
    var_-37 = arg4 & 0x1;
    var_-48 = arg5;
    var_-56 = arg2;
    var_-92 = var_-36 / 0x3;
    if (var_-36 % 0x3 != 0x0) {
            r8 = 0x1;
    }
    var_-60 = var_-92 + r8 << 0x2;
    if ((var_-37 & 0x1) != 0x0) {
            var_-60 = (var_-60 >> 0x6 << 0x1) + var_-60;
    }
    var_-72 = malloc(var_-60 + 0x1);
    if (var_-72 == 0x0) {
            var_-8 = 0x0;
    }
    else {
            var_-76 = 0x0;
            var_-80 = 0x0;
            if ((var_-37 & 0x1) != 0x0) {
                    var_-96 = 0x30;
            }
            else {
                    var_-96 = var_-36;
            }
            var_-84 = var_-96;
            var_-88 = var_-84;
            do {
                    if (var_-88 > var_-36) {
                            var_-88 = var_-36;
                    }
                    while (var_-76 + 0x3 - 0x1 < var_-88) {
                            *(int8_t *)(var_-72 + var_-80) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64(SAR((*(int8_t *)(var_-56 + var_-76) & 0xff & 0xfc), 0x2)));
                            *(int8_t *)(var_-72 + var_-80 + 0x1) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64((*(int8_t *)(var_-56 + var_-76) & 0xff & 0x3) << 0x4 | SAR((*(int8_t *)(var_-56 + var_-76 + 0x1) & 0xff & 0xf0), 0x4)));
                            *(int8_t *)(var_-72 + var_-80 + 0x2) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64((*(int8_t *)(var_-56 + var_-76 + 0x1) & 0xff & 0xf) << 0x2 | SAR((*(int8_t *)(var_-56 + var_-76 + 0x2) & 0xff & 0xc0), 0x6)));
                            rcx = var_-80 + 0x3;
                            var_-80 = rcx + 0x1;
                            *(int8_t *)(var_-72 + rcx) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64(*(int8_t *)(var_-56 + var_-76 + 0x2) & 0xff & 0x3f));
                            var_-76 = var_-76 + 0x3;
                    }
                    if (var_-88 == var_-36) {
                        break;
                    }
                    *(int8_t *)(var_-72 + var_-80) = 0xd;
                    rax = var_-80 + 0x1;
                    var_-80 = rax + 0x1;
                    *(int8_t *)(var_-72 + rax) = 0xa;
                    var_-88 = var_-84 + var_-88;
            } while (true);
            if (var_-76 + 0x1 < var_-36) {
                    *(int8_t *)(var_-72 + var_-80) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64(SAR((*(int8_t *)(var_-56 + var_-76) & 0xff & 0xfc), 0x2)));
                    *(int8_t *)(var_-72 + var_-80 + 0x1) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64((*(int8_t *)(var_-56 + var_-76) & 0xff & 0x3) << 0x4 | SAR((*(int8_t *)(var_-56 + var_-76 + 0x1) & 0xff & 0xf0), 0x4)));
                    *(int8_t *)(var_-72 + var_-80 + 0x2) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64((*(int8_t *)(var_-56 + var_-76 + 0x1) & 0xff & 0xf) << 0x2));
                    rcx = var_-80 + 0x3;
                    var_-80 = rcx + 0x1;
                    *(int8_t *)(var_-72 + rcx) = 0x3d;
            }
            else {
                    if (var_-76 < var_-36) {
                            *(int8_t *)(var_-72 + var_-80) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64(SAR((*(int8_t *)(var_-56 + var_-76) & 0xff & 0xfc), 0x2)));
                            *(int8_t *)(var_-72 + var_-80 + 0x1) = *(int8_t *)("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + sign_extend_64((*(int8_t *)(var_-56 + var_-76) & 0xff & 0x3) << 0x4));
                            *(int8_t *)(var_-72 + var_-80 + 0x2) = 0x3d;
                            rcx = var_-80 + 0x3;
                            var_-80 = rcx + 0x1;
                            *(int8_t *)(var_-72 + rcx) = 0x3d;
                    }
            }
            *(int8_t *)(var_-72 + var_-80) = 0x0;
            if (var_-48 != 0x0) {
                    *(int32_t *)var_-48 = var_-80;
            }
            var_-8 = var_-72;
    }
    rax = var_-8;
    return rax;
}
void * -[UTDIDMain generateUtdidAndSave](void * self, void * _cmd) {
    var_10 = self;
    var_20 = [[UTDIDMain generateUtdid] retain];
    var_28 = [[var_10->mUtdidHelper pack:var_20] retain];
    if (([var_10 isUtdidValid:var_28] & 0x1) == 0x0) {
            var_8 = 0x0;
    }
    else {
            [var_10 saveUtdid:var_28];
            var_8 = [var_20 retain];
    }
    objc_storeStrong(&var_28, 0x0);
    objc_storeStrong(&var_20, 0x0);
    rax = [var_8 autorelease];
    return rax;
}
void * +[UTDIDMain generateUtdid](void * self, void * _cmd) {
    var_18 = [[NSMutableData alloc] init];
    rax = [NSDate date];
    rax = [rax retain];
    var_74 = intrinsic_cvttsd2si([rax timeIntervalSince1970], xmm0);
    [rax release];
    rax = arc4random();
    var_20 = rax - -(rax * 0x80000001 >> 0x3f);
    var_21 = 0x3;
    var_22 = 0x0;
    var_30 = [[UTDIDMain uniqueGlobalDeviceIdentifier] retain];
    rax = [UTDIDIntUtils bytes:var_74];
    rax = [rax retain];
    var_38 = rax;
    [var_18 appendData:rax];
    rax = [UTDIDIntUtils bytes:var_20];
    rax = [rax retain];
    rdi = var_38;
    var_38 = rax;
    [rdi release];
    [var_18 appendData:var_38];
    [var_18 appendBytes:&var_21 length:0x1];
    [var_18 appendBytes:&var_22 length:0x1];
    rax = [UTDIDStringUtils hashCode:var_30];
    rax = [UTDIDIntUtils bytes:rax];
    rax = [rax retain];
    rdi = var_38;
    var_38 = rax;
    [rdi release];
    [var_18 appendData:var_38];
    rax = [UTDIDBaseUtils hmacBase64Value:var_18 key:"d6fc3a4a06adbde89223bvefedc24fecde188aaa9161"];
    rax = [rax retain];
    var_48 = rax;
    rax = [UTDIDStringUtils hashCode:rax];
    rax = [UTDIDIntUtils bytes:rax];
    rax = [rax retain];
    var_58 = rax;
    [var_18 appendData:rax];
    var_88 = [var_18 retain];
    objc_storeStrong(&var_58, 0x0);
    objc_storeStrong(&var_48, 0x0);
    objc_storeStrong(&var_38, 0x0);
    objc_storeStrong(&var_30, 0x0);
    objc_storeStrong(&var_18, 0x0);
    rax = [var_88 autorelease];
    return rax;
}
void * +[UTDIDMain uniqueGlobalDeviceIdentifier](void * self, void * _cmd) {
    var_20 = CFUUIDCreate(0x0);
    var_28 = CFUUIDCreateString(0x0, var_20);
    CFRelease(var_20);
    if (0x0 == var_28) {
            var_8 = [[UTDIDBaseUtils uniqueID] retain];
    }
    else {
            var_8 = [var_28 retain];
    }
    objc_storeStrong(&var_28, 0x0);
    rax = [var_8 autorelease];
    return rax;
}
void * +[UTDIDBaseUtils uniqueID](void * self, void * _cmd) {
    var_18 = [[NSMutableData alloc] init];
    rax = arc4random();
    var_1C = rax - -(rax * 0x80000001 >> 0x3f);
    rax = arc4random();
    var_20 = rax - -(rax * 0x80000001 >> 0x3f);
    rax = arc4random();
    var_24 = rax - -(rax * 0x80000001 >> 0x3f);
    rax = arc4random();
    var_28 = rax - -(rax * 0x80000001 >> 0x3f);
    [var_18 appendBytes:&var_1C length:0x4];
    [var_18 appendBytes:&var_20 length:0x4];
    [var_18 appendBytes:&var_24 length:0x4];
    [var_18 appendBytes:&var_28 length:0x4];
    rax = [UTDIDTypeConvert NSData2Base64:var_18];
    rax = [rax retain];
    var_30 = rax;
    var_58 = [rax retain];
    objc_storeStrong(&var_30, 0x0);
    objc_storeStrong(&var_18, 0x0);
    rax = [var_58 autorelease];
    return rax;
}

(lldb) po [[NSUserDefaults standardUserDefaults]objectForKey:@"UTDID"]

{

    UTDID = "Xh+vQjn4X1ADAM3C7AE95sqH";

    "UTDID_appUID" = "907097C2-DBDC-466E-94EF-9A75EF4D6433";

    "UTDID_createdTS" = "2020-02-27 03:14:51 +0000";

    "UTDID_slot" = "com.UTDID.13";

}

如果已经有值执行顺序 +[UTDIDOpenUDID valueWithError:]

 [NSUserDefaults standardUserDefaults]; var_-80 = [var_-40 objectForKey:@"UTDID"];

 if (([var_-80 isKindOfClass:[NSDictionary class]] & 0x1) == 0x0){

}else{

走这里

var_-48 = [var_-80 objectForKey:@"UTDID"];

if (0x0 != var_-48) {

                            *_kUTDIDOpenUDIDSessionCache = [var_-48 retain];

                            var_-8 = *_kUTDIDOpenUDIDSessionCache;

                    }

rax = var_-8;

    return rax;

}

补充:还原设备,第一次运行走了这个方法utdidmain.说明mpaas没有使用openudid 的 _generateFreshOpenUDID方法(既生成openudid的方法)

发布了130 篇原创文章 · 获赞 15 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/qq_15509071/article/details/104612647