開源框架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的方法)

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章