iOS10.0以上的越狱设备如何使用代码安装IPA?


#1

越狱设备如何使用代码安装IPA

在问这个问题之前,我先说下我知道的8.0如何安装,但是这个在10.0以上已然失效

  • 8.0 使用私有库 编写如下代码可以,但是10.1.1失效
int IPAInstall(NSString *path) {
    
    void *lib = dlopen("/System/Library/PrivateFrameworks/MobileInstallation.framework/MobileInstallation", RTLD_LOCAL);
    
    
    if (lib)
    {
        MobileInstallationInstall pMobileInstallationInstall = (MobileInstallationInstall)dlsym(lib, "MobileInstallationInstall");
        if (pMobileInstallationInstall)
        {
            int ret = pMobileInstallationInstall(path, [NSDictionary dictionaryWithObject:@"User" forKey:@"ApplicationType"], nil, path);
            dlclose(lib);
            
            return ret;
        }
    }
    return -1;
}
  • 通常文件类App都会有安装IPA的功能 (比如Filza,iFile之类)

看了下Filza的安装日志

默认	22:14:58.127894 +0800	installd	0x16f583000 -[MIContainer makeContainerLiveReplacingContainer:reason:withError:]: Made container live for com.unakayou.IPAInstall at /private/var/mobile/Containers/Data/Application/37139E65-1ABE-4BA5-A2A3-511DE6207038
默认	22:14:58.130950 +0800	installd	0x16f583000 -[MIContainer makeContainerLiveReplacingContainer:reason:withError:]: Made container live for com.unakayou.IPAInstall at /private/var/containers/Bundle/Application/E50B6F20-AC85-4D62-A858-70B3203072E6
默认	22:14:58.162609 +0800	installd	com.unakayou.IPAInstall:7:5:2:1:Success (End) : Install (New)
默认	22:14:58.162750 +0800	installd	0x16f583000 -[MIInstaller performInstallationWithError:]: Install Successful for (com.unakayou.IPAInstall); Staging: 0.42s; Waiting: 0.00s; Preflight/Patch: 0.40s, Verifying: 0.03s; Overall: 0.94s
默认	22:15:00.815525 +0800	installd	0x16f583000 -[MIClientConnection enumerateInstalledAppsWithOptions:completion:]: Enumerate installed apps requested by lsd (pid 579) with options {
    UserRequestedAppDBRebuild = 1;
}

大概能看出来它使用的是’’’ /System/Library/PrivateFrameworks/MobileSystemServices.framework’’’'这个私有库

最后我贴一下Filza的安装代码

void -[InstallerViewController install:](void * self, void * _cmd, void * arg2) {

 

    if (r20 != 0x0) {
      
        r25 = @selector(FloatingHeaderEnabled);
        r0 = *(r25 + 0xc68);
        r23 = *(@selector(loopCountdown) + 0x998);
        r0 = objc_msgSend(r0, r23);
        r0 = [r0 retain];
        r20 = r0;
        r21 = *(@selector(directoryPath) + 0x3e8);
        objc_msgSend(r0, r21);
        [r20 release];
        r0 = *(r25 + 0xc68);
        r0 = objc_msgSend(r0, r23);
        r29 = r29;
        r0 = [r0 retain];
        r1 = *(@selector(setProgressView:) + 0x550);
        *(r31 + 0x18) = r24;
        *(r31 + 0x20) = r28;
        r24 = objc_msgSend(r0, r1);
        [r0 release];
        if (r19 != -0x1) {
            r23 = *(r31 + 0x38);
            r28 = *(r31 + 0x8);
            r27 = *(r31 + 0x20);
            if (r24 != 0x0) {
                objc_msgSend(r23, *(@selector(loopCountdown) + 0x740));
                r0 = objc_msgSend(r22, *(@selector(loopCountdown) + 0x340));
                r0 = [r0 retain];
                r19 = r0;
                objc_msgSend(r0, *(@selector(loopCountdown) + 0x1b0));
                [r19 release];
                r19 = NSClassFromString(@"MIInstallerClient");
                r20 = objc_retainBlock(0x10082f860);
                r29 = r29;
                r26 = [objc_msgSend(r19, *(@selector(setProgressView:) + 0x558)) retain];
                [r20 release];
                r19 = *(@selector(setProgressView:) + 0x560);
                if (objc_msgSend(r26, *(@selector(loopCountdown) + 0x2f0)) != 0x0) {
                    r29 = r29;
                    r20 = [objc_msgSend(*(@selector(FloatingHeaderEnabled) + 0xae8), *(@selector(promoActionCancelString) + 0x308)) retain];
                    *(r29 + 0xffffffffffffff50) = *__NSConcreteStackBlock;
                    *(r29 + 0xffffffffffffff58) = *0x1006c5ac0;
                    r8 = 0x1000ea2e0;
                    asm{ nop };
                    *(r29 + 0xffffffffffffff60) = r8;
                    *(r29 + 0xffffffffffffff68) = 0x10082f8b0;
                    *(r29 + 0xffffffffffffff70) = [r23 retain];
                    *(r29 + 0xffffffffffffff78) = [r22 retain];
                    *(r29 + 0xffffffffffffff80) = [r28 retain];
                    r21 = [r27 retain];
                    *(r29 + 0xffffffffffffff88) = r21;
                    r22 = objc_retainBlock(r29 - 0xb0);
                    objc_msgSend(r26, r19);
                    [r22 release];
                    [r20 release];
                    r0 = *(r29 + 0xffffffffffffff88);
                    [r0 release];
                    r0 = *(r29 + 0xffffffffffffff80);
                    [r0 release];
                    r0 = *(r29 + 0xffffffffffffff78);
                    [r0 release];
                    r0 = *(r29 + 0xffffffffffffff70);
                }
                else {
                    r19 = [objc_msgSend(*(@selector(FloatingHeaderEnabled) + 0xdd0), *(@selector(startFetcher:) + 0x318)) retain];
                    r20 = [objc_msgSend(*(@selector(FloatingHeaderEnabled) + 0xae8), *(@selector(promoActionCancelString) + 0x308)) retain];
                    *(r31 + 0xa0) = *__NSConcreteStackBlock;
                    *(r31 + 0xa8) = *0x1006c5ac0;
                    r8 = 0x1000ea714;
                    asm{ nop };
                    *(r31 + 0xb0) = r8;
                    *(r31 + 0xb8) = 0x10082f910;
                    *(r31 + 0xc0) = [r23 retain];
                    *(r31 + 0xc8) = [r22 retain];
                    *(r31 + 0xd0) = [r28 retain];
                    *(r31 + 0xd8) = [r27 retain];
                    r21 = objc_retainBlock(r31 + 0xa0);
                    objc_msgSend(r26, *(@selector(setProgressView:) + 0x578));
                    [r21 release];
                    [r20 release];
                    [r19 release];
                    r0 = *(r31 + 0xd8);
                    [r0 release];
                    r0 = *(r31 + 0xd0);
                    [r0 release];
                    r0 = *(r31 + 0xc8);
                    [r0 release];
                    r0 = *(r31 + 0xc0);
                }
         
        }
        else {
            if (r24 != 0x0) {
                r24 = dlopen("/System/Library/PrivateFrameworks/MobileInstallation.framework/MobileInstallation", r31 | 0x1);
                if (r24 != 0x0) {
                    r19 = dlsym(r24, "MobileInstallationInstall");
                    if (r19 != 0x0) {
                        r29 = r29;
                        r20 = [objc_msgSend(*(@selector(FloatingHeaderEnabled) + 0xae8), *(@selector(promoActionCancelString) + 0x308)) retain];
                        r19 = (r19)(*(r31 + 0x20), r20, zero_extend_64(0x0), *(r31 + 0x18));
                        [r20 release];
                        if (r19 == 0x0) {
                            r0 = *(r25 + 0xc68);
                            r0 = objc_msgSend(r0, r23);
                            r29 = r29;
                            r0 = [r0 retain];
                            r19 = r0;
                            objc_msgSend(r0, r21);
                            [r19 release];
                            r19 = zero_extend_64(0x0);
                        }
                    }
                    else {
                        asm{ movn       w19, #0x0 };
                    }
                    dlclose(r24);
                }
                else {
                    asm{ movn       w19, #0x0 };
                }
            }
            else {
                asm{ movn       w19, #0x0 };
            }
     
    else{
    }

    return;
}

从上面的代码可以看出Filza的作者在安装IPA这个问题上使用了两种方法.应该也是发现文章最前面的私有api MobileInstallation.framework 失效之后另辟的蹊径MobileSystemServices.framework

当然由于我才疏学浅,以上都是纯属个人猜测.回到我的问题…越狱设备如何使用代码安装IPA呢?


#2

你知道了那为什么不照抄他的实现呢


#3

Filza


#4

已修改。谢指正


#5

文章里面都是我的猜测!具体咋实现的不了解。可以看到这个installd。但是还不会调用它。所以想问问大家平时是怎么实现的


#6

#7

有没有在Xcode里面写代码就可以做到的方法


#8

什么是xcode里写代码?我上边贴的那个不能在xcode里写吗?


#9

类似于这样的Xcode工程https://pan.baidu.com/s/1OitNw


#10

一句代码就能安装 appinst (appinst + ipa包的地址)
详情:https://www.jianshu.com/p/892d1c646be6 给个赞就行!


#11

你是Filza作者?