阿里系UTDID庫iOS生成唯一性ID分析

 

上篇說了OpenUDID。

在mpaas裏直接把循環後由+[UTDIDOpenUDID _generateFreshOpenUDID]生成方法改成了[[[UTDIDMain alloc] init] value]

       var_C0 = [var_60 keysSortedByValueUsingSelector:@selector(compare:)];
                    if ((var_C0 != 0x0) && ([var_C0 count] > 0x0)) {
                            var_168 = [var_C0 lastObject];
                    }
                    else {
                            var_168 = 0x0;
                    }
                    var_C8 = var_168;
                    if (var_30 == 0x0) {
                            if (var_C8 == 0x0) {
                                    var_30 = [[[UTDIDMain alloc] init] value];
                            }
                            else {
                                    var_30 = var_C8;
                            }
                            if (var_50 == 0x0) {
                                    var_50 = [NSMutableDictionary dictionaryWithCapacity:0x4];
                                    [var_50 setObject:var_30 forKey:@"UTDID"];
                                    [var_50 setObject:var_68 forKey:@"UTDID_appUID"];
                                    [var_50 setObject:[NSDate date] forKey:@"UTDID_createdTS"];
                                    if ((var_41 & 0x1) != 0x0) {
                                            [var_50 setObject:var_40 forKey:@"UTDID_createdTS"];
                                    }
                                    var_42 = 0x1;
                            }
                    }

UTDIDMain初始化時由UTDIDMain提供 aes祕鑰 , [UTDIDPersistentConf initWithIdentifier:@"Alvin"]持久配置

 

參考:阿里移動數據安全UTDID分析  這篇的先後判斷邏輯。

 

從NSUserDefaults取值

    var_-168 = [NSUserDefaults standardUserDefaults];

    rax = [var_-168 retain];

    var_-56 = rax;

    var_-184 = [rax objectForKey:@"PK_455469921"];

不是空的話dePack 退包,是驗證都是意思嗎?

void * -[UTDIDHelper dePack:](void * self, void * _cmd, void * arg2) {
    objc_storeStrong(&var_80, arg2);

//解密
    var_88 = [[UTDIDAES AES256DecryptWithKey:0x0 forKey:self->mAESKey] retain];
    if ([var_88 length] == 0x16) {
            var_A0 = [[UTDIDBaseUtils platform] retain];
            if (0x0 != var_A0) {
                    var_A8 = [[UTDIDIntUtils bytes:[UTDIDStringUtils hashCode:var_A0]] retain];
                    var_C0 = [[var_88 subdataWithRange:0x0] retain];
                    var_C8 = [[UTDIDIntUtils bytes:0x0] retain];
                    if ((([var_C8 isEqualToData:var_C0] & 0x1) == 0x0) && (([var_A8 isEqualToData:var_C0] & 0x1) == 0x0)) {
                            var_68 = 0x0;
                            var_CC = 0x1;
                    }
                    else {
                            var_CC = 0x0;
                    }
                    objc_storeStrong(&var_C8, 0x0);
                    objc_storeStrong(&var_C0, 0x0);
                    objc_storeStrong(&var_A8, 0x0);
                    if (var_CC == 0x0) {
                            var_E8 = [[var_88 subdataWithRange:0x4] retain];
                            var_68 = [var_E8 retain];
                            objc_storeStrong(&var_E8, 0x0);
                    }
            }
            else {
                    var_E8 = [[var_88 subdataWithRange:0x4] retain];
                    var_68 = [var_E8 retain];
                    objc_storeStrong(&var_E8, 0x0);
            }
            objc_storeStrong(&var_A0, 0x0);
    }
    else {
            var_68 = 0x0;
    }
    var_80 = 0x0;
    objc_storeStrong(&var_88, 0x0);
    objc_storeStrong(&var_80, 0x0);
    rax = [var_68 autorelease];
    return rax;
}

解密,取設備平臺hw.machine,然後每個字節比對。

是空的話也解密?然後[var_10->mDevicePersistentConfig setObject:var_40 forKey:@"c"];

然後生成與存儲

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;
}

+[UTDIDMain generateUtdid] 

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;
}

上面是核心算法:取時間戳 隨機數

然後用系統方法創建uuid

void * +[UTDIDMain uniqueGlobalDeviceIdentifier](void * self, void * _cmd) {
    var_-32 = CFUUIDCreate(0x0);
    var_-40 = CFUUIDCreateString(0x0, var_-32);
    CFRelease(var_-32);
    if (0x0 == var_-40) {
            var_-8 = [[UTDIDBaseUtils uniqueID] retain];
    }
    else {
            var_-8 = [var_-40 retain];
    }
    objc_storeStrong(&var_-40, 0x0);
    rax = [var_-8 autorelease];
    return rax;
}

 var_-8 = [[UTDIDBaseUtils uniqueID] retain];這個基本用不上。

然後生成hmac,rax = [UTDIDBaseUtils hmacBase64Value:var_-24 key:"d6fc3a4a06adbde89223bvefedc24fecde188aaa9161"];

拼接二進制,再轉字節,

 

猜的沒錯,斷點截圖

核心代碼試着放到工程裏更直觀的看看

//
//  UTDIDMain+YYY.h
//
//  Created by YYY on 2020/3/4.
//



NS_ASSUME_NONNULL_BEGIN
@interface UTDIDMain : NSObject
+ (id)uniqueGlobalDeviceIdentifier;
@end
@interface UTDIDMain (YYY)

@end

NS_ASSUME_NONNULL_END


//
//  UTDIDMain+YYY.m
//
//  Created by YYY on 2020/3/4.
//

#import "UTDIDMain+YYY.h"
#import <objc/runtime.h>
@interface UTDIDIntUtils : NSObject
{
}

+ (id)bytes:(unsigned int)arg1;
+ (int)positive:(int)arg1;
@end


@interface UTDIDStringUtils : NSObject
{
}

+ (int)hashCode:(id)arg1;
+ (_Bool)isEmpty:(id)arg1;

@end

@interface UTDIDBaseUtils : NSObject
{
}

+ (id)hmacBase64Value:(id)arg1 key:(char *)arg2;
+ (id)platform;
+ (id)uniqueID;

@end
@implementation UTDIDMain (YYY)
+(NSData*)generateUtdidS {
    

    NSMutableData *var_24 = [[NSMutableData alloc] init];
    NSDate *rax0 = [NSDate date];//2020-03-03 16:33:21 +0000
    
    NSTimeInterval var_116 = [rax0 timeIntervalSince1970];//1583253201.224169
    
    uint32_t rax1 = arc4random();//3935423772
    uint32_t var_32 = (rax1 * 0x80000001 >> 0x3f);//0
    int var_33 = 0x3;
    int var_34 = 0x0;
    
    NSString *var_48 =  [UTDIDMain uniqueGlobalDeviceIdentifier]  ;//F37FA956-45E4-4CB6-811A-AA2C9CB03D75
    NSData *rax2 = [UTDIDIntUtils bytes:var_116];//<5e5e86d1>
    NSData *var_56 = rax2;
    
    [var_24 appendData:rax2];//第一步 先拼時間戳生成的dbyte
    
    NSData * rax3 = [UTDIDIntUtils bytes:var_32];//
    
    NSData *rdi = var_56;
    var_56 = rax3;
    
    
    [var_24 appendData:var_56];//第二步  拼接隨機數右移的值
    [var_24 appendBytes:&var_33 length:0x1];//第3步  拼接1
    [var_24 appendBytes:&var_34 length:0x1];//第4步  拼接1
    
    Byte rax4 = [UTDIDStringUtils hashCode:var_48];
    NSData* rax5 = [UTDIDIntUtils bytes:rax4];//<00000057>
    
    rdi = var_56;
    var_56 = rax5;
    
    [var_24 appendData:var_56];////第5步  拼接uniqueGlobalDeviceIdentifier hashCode的值
    
    NSData*  rax6 = [UTDIDBaseUtils hmacBase64Value:var_24 key:"d6fc3a4a06adbde89223bvefedc24fecde188aaa9161"];//zBc/8BGEZzWAAEgG0shNPItLQs8=

    
    int  rax7 = [UTDIDStringUtils hashCode:rax6];//-797734293
    NSData  *rax8 = [UTDIDIntUtils bytes:rax7];//<d0738a6b>

    
    [var_24 appendData:rax8];//第6步  拼接hmacBase64Value hashCode的值
    
    NSData*  var_136 =  var_24 ;

    
    return var_136;//<5e5e86d1 00000000 03000000 0057d073 8a6b>

}
@end

 

總結核心代碼生成步驟:

//第一步 先拼時間戳生成的byte

//第二步  拼接隨機數右移的值

//第3步  拼接3

//第4步  拼接0

//第5步  拼接uniqueGlobalDeviceIdentifier hashCode的值

//第6步  拼接hmacBase64Value hashCode的值

 

 

 

 

 

 

 

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