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文件也不多

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

猜你喜欢

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