mPaaS蘋果客戶端檢查更新的僞源碼探究

 

檢查更新的方法是

    
[[UpgradeCheckService sharedService]checkUpgradeWith:^(MOBILEAPPCOMMONClientUpgradeRes *response) {


} failure:^(NSException *error) {


}];



這是返回的字段

@interface MOBILEAPPCOMMONClientUpgradeRes : NSObject

@property(nonatomic, assign) SInt32 resultStatus;
@property(nonatomic, strong) NSString* memo;
@property(nonatomic, strong) NSString* downloadURL;
@property(nonatomic, strong) NSString* newestVersion;
@property(nonatomic, strong) NSString* guideMemo;
@property(nonatomic, strong) NSString* fullMd5;
@property(nonatomic, strong) NSString* upgradeVersion;
@property(nonatomic, strong) NSString* netType;
@property(nonatomic, strong) NSString* userId;
@property(nonatomic, assign) BOOL isTf;

@end


這個是聲明

/**
 * 主動檢查更新,異步髮網絡請求
 * 業務方有自定義UI需求時可調用
 */
- (void)checkUpgradeWith:(CheckUpgradeComplete)complete failure:(CheckUpgradeFailure)failure;

hopper一下 [UpgradeCheckService sharedService]  功能是聲明rpc

/* @class UpgradeCheckService */
+(void *)sharedService {
    if (*_sharedService.onceToken != 0xffffffffffffffff) {
            dispatch_once(_sharedService.onceToken, ^ {/* block implemented at ___36+[UpgradeCheckService sharedService]_block_invoke */ } });
    }
    rax = objc_retainAutoreleaseReturnValue(*_sharedService.service);
    return rax;
}


void ___36+[UpgradeCheckService sharedService]_block_invoke(void * _block) {
    rax = [UpgradeCheckService alloc];
    rax = [rax init];
    rdi = *_sharedService.service;
    *_sharedService.service = rax;
    [rdi release];
    r12 = [[DTRpcConfig alloc] init];
    [r12 setOperationType:@"alipay.client.updateVersion"];
    r14 = [[DTRpcInterface sharedInstance] retain];
    r13 = [[r14 uniformRpcGateway] retain];
    rbx = [[NSURL URLWithString:r13] retain];
    [r12 setGatewayURL:rbx];
    [rbx release];
    [r13 release];
    [r14 release];
    [r12 setIsAMRPC:0x1];
    rbx = [[DTRpcClient defaultClient] retain];
    [rbx setConfig:r12 forScope:0x2];
    [rbx release];
    [r12 release];
    return;
}

 

下面hopper一下代碼實現 arg2 ->rbx 這是完成的block

/* @class UpgradeCheckService */
-(void)checkUpgradeWith:(void *)arg2 failure:(void *)arg3 {
    rbx = [arg2 retain];
    [CheckUpdateNetwork checkAppVersion:rbx failure:arg3];
    [rbx release];
    return;
}

直接調用了另一個類方法。+(void)checkAppVersion:(void *)arg2 failure:(void *)arg3 
  checkAppVersion調用的sharedService

/* @class CheckUpdateNetwork */
+(void)checkAppVersion:(void *)arg2 failure:(void *)arg3 {
    stack[-80] = [arg2 retain];
    rax = [arg3 retain];
    stack[-192] = 0x0;
    *(&stack[-192] + 0x8) = &stack[-192];
    *(&stack[-192] + 0x10) = 0x3032000000;
    *(int128_t *)(&stack[-192] + 0x18) = intrinsic_movdqu(*(int128_t *)(&stack[-192] + 0x18), intrinsic_punpcklqdq(zero_extend_64(___Block_byref_object_copy_), zero_extend_64(___Block_byref_object_dispose_)));
    rbx = rax;
    *(&stack[-192] + 0x28) = 0x0;
    r13 = [[self shredReq] retain];//req類型
    rax = [ClientUpgradeFacade new];
    stack[-144] = *__NSConcreteStackBlock;
    *(&stack[-144] + 0x8) = 0xffffffffc2000000;
    *(&stack[-144] + 0x10) = ___46+[CheckUpdateNetwork checkAppVersion:failure:]_block_invoke;
    *(&stack[-144] + 0x18) = ___block_descriptor_tmp.8;
    *(&stack[-144] + 0x38) = &stack[-192];
    rax = [rax retain];
    stack[-56] = rax;
    *(&stack[-144] + 0x20) = rax;
    r13 = [r13 retain];
    *(&stack[-144] + 0x28) = r13;
    rax = [rbx retain];
    stack[-64] = rax;
    *(&stack[-144] + 0x30) = rax;
    stack[-240] = *__NSConcreteStackBlock;
    *(&stack[-240] + 0x8) = 0xffffffffc2000000;
    *(&stack[-240] + 0x10) = ___46+[CheckUpdateNetwork checkAppVersion:failure:]_block_invoke.9;
    *(&stack[-240] + 0x18) = ___block_descriptor_tmp.16;
    *(&stack[-240] + 0x28) = &stack[-192];
    r14 = [stack[-80] retain];
    *(&stack[-240] + 0x20) = r14;
    rax = [DTRpcAsyncCaller callAsyncBlock:&stack[-144] completion:&stack[-240]];
    [[rax retain] release];
    [stack[-208] release];
    [stack[-96] release];
    [stack[-104] release];
    [stack[-112] release];
    [stack[-56] release];
    [r13 release];
    _Block_object_dispose(&stack[-192], 0x8);
    [*(&stack[-192] + 0x28) release];
    [stack[-64] release];
    [r14 release];
    return;
}

先看[self shredReq]  獲取設備信息,聯網狀態,從info.plist取出了@"Product ID"@"Product Version"等字段

是這麼取的

    r14 = [[NSBundle mainBundle] retain];

    rbx = [[r14 objectForInfoDictionaryKey:@"Product Version"] retain];

 

/* @class CheckUpdateNetwork */
+(void *)shredReq {
    r12 = [[MOBILEAPPCOMMONClientUpgradeReq alloc] init];
    rax = [APMobileIdentifier shareIdentifier];
    rax = [rax retain];
    stack[-80] = rax;
    rbx = [[rax clientId] retain];
    [r12 setClientId:rbx];
    r14 = *_objc_release;
    [rbx release];
    r15 = [[UIDevice currentDevice] retain];
    rbx = [[r15 systemVersion] retain];
    [r12 setOsVersion:rbx];
    [rbx release];
    [r15 release];
    r15 = [[NSBundle mainBundle] retain];
    r14 = [[r15 objectForInfoDictionaryKey:@"Product ID"] retain];
    [r12 setProductId:r14];
    [r14 release];
    [r15 release];
    r14 = [[NSBundle mainBundle] retain];
    rbx = [[r14 objectForInfoDictionaryKey:@"Product Version"] retain];
    [r12 setProductVersion:rbx];
    [rbx release];
    [r14 release];
    rbx = [[stack[-80] UTDID] retain];
    [r12 setDid:rbx];
    [rbx release];
    [r12 setOsType:@"IOS"];
    rbx = [[DTReachability sharedDTReachability] retain];
    r14 = [rbx networkStatus];
    [rbx release];
    if (r14 != 0x2) goto loc_101927e7c;

loc_101927e6c:
    rdx = @"WIFI";
    goto loc_101927ec1;

loc_101927ec1:
    [r12 setNetType:rdx];
    goto loc_101927eca;

loc_101927eca:
    stack[-56] = **___stack_chk_guard;
    [r12 setPrisonBreak:(*([_APSecurityUtilImpl shared] + 0x20))(0x0) & 0xff];
    [r12 setMobileBrand:@"Apple"];
    rax = [CTTelephonyNetworkInfo alloc];
    rax = [rax init];
    rdi = *_gNetWrokInfo;
    *_gNetWrokInfo = rax;
    [rdi release];
    rbx = [[stack[-80] deviceModel] retain];
    [r12 setMobileModel:rbx];
    [rbx release];
    r14 = [[MPaaSInterface sharedInstance] retain];
    rbx = [[r14 userId] retain];
    [r12 setUserId:rbx];
    [rbx release];
    [r14 release];
    stack[-72] = @"prisonBreakFlag";
    r15 = [[CheckUpdateNetwork getYueyuInfoFromDeviceInfo] retain];
    stack[-64] = r15;
    rax = [NSDictionary dictionaryWithObjects:&stack[-64] forKeys:&stack[-72] count:0x1];
    rbx = [rax retain];
    [r12 setExtInfos:rbx];
    [rbx release];
    [r15 release];
    [stack[-80] release];
    if (**___stack_chk_guard == stack[-56]) {
            rax = [r12 autorelease];
    }
    else {
            rax = __stack_chk_fail();
    }
    return rax;

loc_101927e7c:
    rbx = [[DTReachability sharedDTReachability] retain];
    r14 = [rbx networkStatus];
    [rbx release];
    if (r14 != 0x1) goto loc_101927eca;

loc_101927eb3:
    rdx = @"WWAN";
    goto loc_101927ec1;
}

這裏還會檢查越獄

螞蟻的的命名也是這樣啊哈哈哈  getYueyuInfoFromDeviceInfo

/* @class CheckUpdateNetwork */
+(void *)getYueyuInfoFromDeviceInfo {
    r14 = @"-1";
    [r14 retain];
    rbx = [NSClassFromString(@"AliSecXDeviceInfo") retain];
    if (rbx != 0x0) {
            r14 = @"-1";
            if ([rbx respondsToSelector:@selector(isYyabcInfo)] != 0x0) {
                    [rbx performSelector:@selector(isYyabcInfo)] & 0xffff;
                    r14 = [[NSString stringWithFormat:@"%d"] retain];
                    [@"-1" release];
            }
    }
    [rbx release];
    rax = [r14 autorelease];
    return rax;
}

ClientUpgradeFacade是更新表面的意思嗎 

    stack[-104] = [[r14 executeMethod:rdx params:rcx requestHeaderField:r8 responseHeaderFields:0x0] retain];
這行發請求

 

/* @class ClientUpgradeFacade */
-(void *)versionUpdateCheck:(void *)arg2 {
    rbx = [arg2 retain];
    r13 = [[DTRpcMethod alloc] init];
    [r13 setOperationType:@"alipay.client.updateVersion"];
    [r13 setCheckLogin:0x0];
    [r13 setSignCheck:0x1];
    [r13 setRetryable:0x0];
    [r13 setReturnType:@"@\"MOBILEAPPCOMMONClientUpgradeRes\""];
    r14 = [[DTRpcClient defaultClient] retain];
    stack[-112] = rbx;
    if (rbx != 0x0) {
            stack[-84] = 0x0;
    }
    else {
            rbx = [[NSNull null] retain];
            stack[-84] = 0x1;
    }
    stack[-96] = rbx;
    stack[-64] = rbx;
    rax = [NSArray arrayWithObjects:&stack[-64] count:0x1];
    rbx = [rax retain];
    stack[-80] = @"Version";
    stack[-72] = @"2";
    rax = [NSDictionary dictionaryWithObjects:&stack[-72] forKeys:&stack[-80] count:0x1];
    r15 = [rax retain];
    rdx = r13;
    rcx = rbx;
    r8 = r15;
    stack[-104] = [[r14 executeMethod:rdx params:rcx requestHeaderField:r8 responseHeaderFields:0x0] retain];
    [r15 release];
    [rbx release];
    if (stack[-84] != 0x0) {
            [stack[-96] release];
    }
    stack[-56] = **___stack_chk_guard;
    [r14 release];
    [r13 release];
    [stack[-112] release];
    if (**___stack_chk_guard == stack[-56]) {
            rax = [stack[-104] autorelease];
    }
    else {
            rax = __stack_chk_fail();
    }
    return rax;
}

然後根據MOBILEAPPCOMMONClientUpgradeRes反推一下

00000001024cbc68         dq         0x00000001040559e8, 0x00000000000007c8, 0x00000001020681b3, 0x0000000000000022 ; "@\\\"MOBILEAPPCOMMONClientUpgradeRes\\\"", DATA XREF=-[ClientUpgradeFacade versionUpdateCheck:]+158

可見就是上面的方法。

    r13 = [[DTRpcMethod alloc] init];

    [r13 setReturnType:@"@\"MOBILEAPPCOMMONClientUpgradeRes\""];

設置ReturnType之後返回的數據直接轉爲MOBILEAPPCOMMONClientUpgradeRes模型

 

DTRpcMethod作爲DTRpcClient方法的參數

    stack[-104] = [[r14 executeMethod:rdx params:rcx requestHeaderField:r8 responseHeaderFields:0x0] retain];

 

ClientUpgradeFacade繼承與nsobject  只有一個方法versionUpdateCheck

  ; 
                             ; @metaclass ClientUpgradeFacade  {
                             ; }
                     _OBJC_METACLASS_$_ClientUpgradeFacade:
000000010293ff28         struct __objc_class {                                  ; DATA XREF=_OBJC_CLASS_$_ClientUpgradeFacade
                             _OBJC_METACLASS_$_NSObject,          // metaclass
                             _OBJC_METACLASS_$_NSObject,          // superclass
                             __objc_empty_cache,                  // cache
                             0x0,                                 // vtable
                             __objc_metaclass_ClientUpgradeFacade_data // data
                         }
                             ; 
                             ; @class ClientUpgradeFacade : NSObject {
                             ;     -versionUpdateCheck:
                             ; }
                     _OBJC_CLASS_$_ClientUpgradeFacade:
000000010293ff50         struct __objc_class {                                  ; DATA XREF=0x102503bf8, objc_cls_ref_ClientUpgradeFacade
                             _OBJC_METACLASS_$_ClientUpgradeFacade, // metaclass
                             _OBJC_CLASS_$_NSObject,              // superclass
                             __objc_empty_cache,                  // cache
                             0x0,                                 // vtable
                             __objc_class_ClientUpgradeFacade_data // data
                         }

 

 

mov        rdi, qword [objc_cls_ref_ClientUpgradeFacade] ; argument "instance" for method _objc_msgSend, objc_cls_ref_ClientUpgradeFacade

 [ClientUpgradeFacade new];  咋調用的versionUpdateCheck?它的參數哪裏來的?

看這裏

    *(&var_88 + 0x10) = ___46+[CheckUpdateNetwork checkAppVersion:failure:]_block_invoke;

    *(&var_E8 + 0x10) = ___46+[CheckUpdateNetwork checkAppVersion:failure:]_block_invoke.9;

這個block裏面代碼裏調用的,竟然直接搜,搜不到

這是failure的block
function ___46+[CheckUpdateNetwork checkAppVersion:failure:]_block_invoke.9 {
    var_-56 = __NSConcreteStackBlock;
    *(int32_t *)(&var_-56 + 0x8) = 0xc2000000;
    *(int32_t *)(&var_-56 + 0xc) = 0x0;
    *(&var_-56 + 0x10) = ___46+[CheckUpdateNetwork checkAppVersion:failure:]_block_invoke_2.10;
    *(&var_-56 + 0x18) = ___block_descriptor_tmp.13;
    *(&var_-56 + 0x28) = *(rdi + 0x28);
    *(&var_-56 + 0x20) = [*(rdi + 0x20) retain];
    dispatch_async(__dispatch_main_q, &var_-56);
    rax = [*(&var_-56 + 0x20) release];
    return rax;
}
function ___46+[CheckUpdateNetwork checkAppVersion:failure:]_block_invoke_2.10 {
    rax = *(*(rdi + 0x28) + 0x8);
    if (*(rax + 0x28) != 0x0) {
            rdi = *(rdi + 0x20);
            if (rdi != 0x0) {
                    rax = (*(rdi + 0x10))();
            }
    }
    return rax;
}

 

 

更新的邏輯還是很清晰的,這個framefork文件也不多

 

 

 

 

 

 

 

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