背景:公司的竞品分析业务,需要下载appstore竞品app来分析
目前方案: wda下载app,非完美越狱后破壳、dump头文件。
弊端:流程繁琐,稳定性差(目前成功率在80%以上),且无法覆盖历史版本。
越狱市场有叫 appstore++的插件,可以实现下载appstore 任意应用任意历史包。这是我们想要的效果,但是appstore++都是基于页面操作来完成,无法实现自动化。
趁着下午时间空闲,看看apsptore++实现,防止自己忘掉,留下此文章,以便自己找回或者方便后人继续研究。
历史版本
分析了appstore++中的 appstoreplusSB.dylib
动态库,发现他的历史版本其实是通过接口传入bundleId拉取到的。
例如: https://mixrank.com/appstore/apps/529479190/versions
下载历史版本
appstore++ 执行下载的方法
-[ASPPSpringBoardUtils completeDowngradeWithAdamId:externalId:](void * self, void * _cmd, void * arg2, void * arg3)
调用 ios下载的代码
[[SKUIItemStateCenter defaultCenter] _performPurchases:NSArray<SKUIItem *>) *item hasBundlePurchase:(BOOL) purchased withClientContext:(SKUIClientContext *)context completeBlock:nil]
解读:
参数1:SKUIItem
下载项,可同时下载多个。
r10 = [objc_getClass("SKUIItem") alloc];
[r10 setItemIdentifier:r2]; // r2 = SKUIItemOffer
[r10 setValue:r8 forKey:@"_itemOffer"]; // r8 = AdamId
[r10 setValue:@"iosSoftware" forKey:@"_itemKindString"];
[r10 setValue:stack[2028] forKey:@"_versionIdentifier"]; // stack[2028] = externalId
参数2:SKUIClientContext
单利,直接 调用 [SKUIClientContext defaultContext] 为空,应该是打开appstore且有下载应用时才会有值。
后续自动化思路
由于必须获取到 上下文,所以可以写一个 demaeon 服务,实现 唤起appstore,接收下载指定版本指令,砸壳,回传Agent。
ps:由于时间问题, 自己到目前还未实现,也许此路不通。如果有人基于此思路实现,希望可以在下面评论方案可行,方便后人。谢谢