IOS应用内购本地防破解

关于IAP的知识,在苹果的开发者网站都能找到。 IAP部署图如下所示:

苹果通过提供StoreKit框架来帮助客户端实现IAP,StoreKit和App Store之间的通讯,主要提供两个功能:

  1. StoreKit从App Store取回可以提供的内购项目
  2. StoreKit向App Store提出付费请求,并把付费完成的消息通知客户端

至于客户端和“Your Server”的通讯,其实跟IAP框架没什么关系,开发者根据自己的情况,决定用户付费成功后,是从服务器下载数据,还是直接暴露新的功能给用户。

以Helicopter Sim这款游戏举例,内购的关卡并不需要从服务器下载。

那么我们就有机会在一次失败的购买过程中,在Store Kit把购买失败的消息通知给客户端之前,把购买失败的消息篡改成购买成功的消息。

Store Kit中购买的状态有以下5种,

enum {
SKPaymentTransactionStatePurchasing,
SKPaymentTransactionStatePurchased,
SKPaymentTransactionStateFailed,
SKPaymentTransactionStateRestored,
SKPaymentTransactionStateDeferred,
};
typedef NSInteger SKPaymentTransactionState;

它们都封装在SKPaymentTransaction中,通过SKPaymentTransactionObserver的回调函数
(void)paymentQueue:(SKPaymentQueue )queue updatedTransactions:(NSArray )transactions
告诉给客户端。

那么我们就可以在上述回调函数中加入如下逻辑:

if (SKPaymentTransaction.transactionState == SKPaymentTransactionStateFailed)
{
SKPaymentTransaction.transactionState = SKPaymentTransactionStatePurchased
}

具体的实现方法,发挥一下想象,可以用补丁在代码中加入上述逻辑,也可以用调试器动态的修改内存或者寄存器。 上述逻辑准备好以后,点击内购项目进行购买,在弹出对话框要求输入App Store的密码的时候,点击取消,这时上面的逻辑就会起作用。 当这一切结束的时候,你就会发现,你点击的关卡已经出现在你的游戏中:)

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在Objective-C分类目录。将固定链接加入收藏夹。