0x1 目标介绍
目标App能够帮助你了解世界各地的风土人情,是学习各国语言的必备佳品,可惜的是,启动后就有显眼的广告(底部),而且默认只能学习美式英语,比如飘哥想要学习一下法语,则要开启”高级“功能才行,如下图所示。
开发者也是挺“人性化”的,右下角显眼位置提供了一个”订阅“指引,点进去看看,原来是个内购页面,如图所示。 
嗯!本文就尝试从新手的角度来破解这些限制。
0x2 不需具备的知识
本文不需要你了解LLDB、IDA、Hopper等分析调试工具,不需要你了解任何ARM汇编知识! 需要了解啥呢?这是个好问题!你只需要会敲命令行即可!!
本文涉及的代码只有一行!学完后你可以正儿八经的吹个牛B:“哥一行代码破解xxx”。
0x3 安装Frida
Frida是一个跨平台的轻量级Hook框架,支持所有主流操作系统,它可以帮助逆向人员对指定的进程进行分析。它主要提供了精简的Python接口和功能丰富的JS接口,除了使用自身的控制台交互以外,还可以利用Python将JS脚本库注入到目标进程。使用Frida可以获取进程详细信息、拦截和调用指定函数、注入代码、修改参数、从iOS应用程序中dump类和类方法信息等。 Frida需要安装控制端(macOS端)与被控端(iOS端),两端的版本号最好保持一致,否则可能无法正常工作。
1.被控端(iOS端)

2.控制端(macOS端)
控制端可以安装到Windows、macOS、Linux等平台,本文仅以macOS平台为例讲解。
使用sudo权限,利用pip安装frida及frida-tools,如下:
[Bash shell] 纯文本查看 复制代码
$ sudo pip install frida
$ sudo pip install frida-tools
$ frida --version
12.6.18
0x4 寻找切入点
以前教程都用IDA之类的寻找切入点,由于本文是新手教程,那么就直接利用frida-trace进行试探,由于有免费试用,所以飘哥选择用FreeTrial关键字在作死的边缘反复进行试探,命令行如下:
[Bash shell] 纯文本查看 复制代码 $ frida-trace -U -f com.apalonapps.xxxapp -m "*[* *FreeTrial*]"
Instrumenting functions...
-[APMInAppPurchaseItem isFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APMInAppPurchaseItem_isFreeTrial_.js"
-[APMInAppPurchaseItem setFreeTrial:]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APMInAppPurchaseItem_setFreeTrial__.js"
+[APNInAppProduct localizedStartMyFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedStart_0b3c8fc5.js"
+[APNInAppProduct localizedJoinWithFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedJoinW_14c42d59.js"
+[APNInAppProduct localizedSubscribeWithFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedSubsc_3ef5833c.js"
+[APNInAppProduct localizedStartFreeTrialAndSubscribe]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedStart_-4b087cfa.js"
+[APNInAppProduct localizedEnrollWithFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedEnrol_-1c75f8e9.js"
-[APNInAppProduct localizedPeriodFreeTrialString]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedPerio_5aa8eee7.js"
-[APNInAppProduct localizedStartFreeTrialString]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedStart_-19f8503b.js"
-[APNInAppProduct localizedStartYourNdayFreeTrialString]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedStart_6bd91611.js"
-[APNInAppProduct localizedNDayFreeTrialRenews]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNInAppProduct_localizedNDayF_-63a0ffb1.js"
-[ICMusicSubscriptionStatus isInFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__ICMusicSubscriptionStatus_isIn_-1cb12cd0.js"
-[ICMusicSubscriptionStatus isEligibleForFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__ICMusicSubscriptionStatus_isEl_1207a9d0.js"
-[APNSubscriptionsManager isActiveSubscriptionInFreeTrialPeriod]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNSubscriptionsManager_isActi_-1800081e.js"
-[APNSubscriptionsManager isFreeTrial]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNSubscriptionsManager_isFreeTrial_.js"
-[APNSubscriptionsManager setIsFreeTrial:]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNSubscriptionsManager_setIsF_39d6e6dd.js"
-[SSVSubscriptionStatus setFreeTrialIneligible:]: Loaded handler at "/Users/piao/Desktop/__handlers__/__SSVSubscriptionStatus_setFreeT_06feffb6.js"
-[SSVSubscriptionStatus isFreeTrialIneligible]: Loaded handler at "/Users/piao/Desktop/__handlers__/__SSVSubscriptionStatus_isFreeTr_-0038832.js"
Started tracing 18 functions. Press Ctrl+C to stop.
此时会在命令行所在目录下生成一个“__handles__”文件夹,里面是生成的JS文件,先不要管他们。 现在解释几个关键参数:
- -U:表示USB连接
- -f:表示启动某个进程(后面跟着应用的bundleId)
- -m:对Object-C的方法进行追踪(你也可以叫Hook),后面可以更各种模糊匹配等等。
成功Hook了一堆方法(函数),遗憾的是,直到进入界面都没触发相关的方法,那么我们进入内购页面试试看,点击“订购套餐并享受试用”,由于飘哥大写的Qiong,所以在随后支付窗口中当然点击“取消”,土豪随意! 此时控制台总算有反应了:
[Bash shell] 纯文本查看 复制代码 /* TID 0x403 */
215349 ms -[APNSubscriptionsManager isFreeTrial]
很好,看来前戏很重要哦!!现在全面追踪APNSubscriptionsManager类的所有方法,如下:
[Bash shell] 纯文本查看 复制代码 $ frida-trace -U -f com.apalonapps.xxxapp -m "*[APNSubscriptionsManager *]"
.
.
.
Started tracing 87 functions. Press Ctrl+C to stop.
/* TID 0x403 */
540 ms -[APNSubscriptionsManager initWithSegmentProductIDs:0x0 serverValidationConfig:0x28103c020 reachabilityHostname:0x103202d90 customIdParsing:0x281e5d5c0]
540 ms | -[APNSubscriptionsManager initWithSegmentProductIDs:0x0 serverValidationConfig:0x28103c020 reachabilityHostname:0x103202d90 customIdParsing:0x281e5d5c0 subscriptionStatusDidCheckedInCurrentSession:0x0]
541 ms | | -[APNSubscriptionsManager updateSegmentProductIDs:0x0]
541 ms | | -[APNSubscriptionsManager initializeStorePurchasesObserver]
541 ms | | -[APNSubscriptionsManager setInitialSubscriptionStatus]
541 ms | | | -[APNSubscriptionsManager activeSubscription]
541 ms | | -[APNSubscriptionsManager checkForActiveSubscriptionOnSessionStart]
541 ms | | | -[APNSubscriptionsManager purchaseInProgress]
541 ms | | | -[APNSubscriptionsManager setCheckIsInProgess:0x1]
541 ms | | | -[APNSubscriptionsManager checkForActiveSubscriptionWithCompletion:0x16d284b70]
548 ms -[APNSubscriptionsManager setErrorHandler:0x281205340]
548 ms -[APNSubscriptionsManager setSubscriptionStatusDidChanged:0x1031cb0d0]
548 ms -[APNSubscriptionsManager setSubscriptionPaymentDidMade:0x16d284d18]
548 ms -[APNSubscriptionsManager hasActiveSubscription]
556 ms -[APNSubscriptionsManager canMakeAppStorePurchase]
557 ms -[APNSubscriptionsManager setCanMakeAppStorePurchase:0x16d284f00]
.
.
.
好了,这次高C了,调用了一堆方法,先别去管他,点击一下服务器列表,继续看方法调用:
[Bash shell] 纯文本查看 复制代码 168571 ms -[APNSubscriptionsManager hasActiveSubscription]
168572 ms -[APNSubscriptionsManager hasActiveSubscription]
168572 ms -[APNSubscriptionsManager hasActiveSubscription]
168572 ms -[APNSubscriptionsManager hasActiveSubscription]
168573 ms -[APNSubscriptionsManager hasActiveSubscription]
168573 ms -[APNSubscriptionsManager hasActiveSubscription]
168573 ms -[APNSubscriptionsManager hasActiveSubscription]
168574 ms -[APNSubscriptionsManager hasActiveSubscription]
168574 ms -[APNSubscriptionsManager hasActiveSubscription]
168574 ms -[APNSubscriptionsManager hasActiveSubscription]
168575 ms -[APNSubscriptionsManager hasActiveSubscription]
168575 ms -[APNSubscriptionsManager hasActiveSubscription]
这里反复调用hasActiveSubscription方法,从字面意义来看就知道在检测是否激活了“订阅”功能(开发者说可以全功能试用)。 此时当然是没有激活!想办法激活它会怎么样?
0x5 飞向光明之巅
既然是新手教程,当然不去分析其代码实现。通过观察日志,我们注意到该方法在App启动时就会调用,嘿嘿,那么接下来干吗呢?找到frida-trace生成的JS文件,稍微添加一行代码如下图所示: 大家别慌,这些代码都是frida-trace自动生成的,你只要大概知道onEnter是进入函数时执行,onLeave是离开函数时执行即可,那么飘哥刚刚加入的retval.replace(1);代码意思就是在离开函数时将返回值改为1(true)。 此时用明确的脚本调用来启动进程,如下: [Bash shell] 纯文本查看 复制代码 $ frida-trace -U -f com.apalonapps.xxxapp -m "-[APNSubscriptionsManager hasActiveSubscription]"
Instrumenting functions...
-[APNSubscriptionsManager hasActiveSubscription]: Loaded handler at "/Users/piao/Desktop/__handlers__/__APNSubscriptionsManager_hasAct_14ba39f8.js"
Started tracing 1 function. Press Ctrl+C to stop.
/* TID 0x403 */
482 ms -[APNSubscriptionsManager hasActiveSubscription]
710 ms -[APNSubscriptionsManager hasActiveSubscription]
748 ms -[APNSubscriptionsManager hasActiveSubscription]
749 ms -[APNSubscriptionsManager hasActiveSubscription]
.
.
.
.
经过一番云雨之后,进入了界面,此时心情还是非常激动的,因为底部的广告条没了~~~~,哈哈,如下图: 点击服务器列表,随意点击个服务器试试,貌似全部可用了,如下图。 
点击试试功能完全正常,如下图所示。
0x6 插件实现 这部分你们找diao大的C版帮编译吧,哈哈哈~~~~
[Objective-C] 纯文本查看 复制代码 %hook APNSubscriptionsManager
- (bool) hasActiveSubscription {
return YES;
}
%end |