大脸猫讲逆向之 iOS上PDFExpert阅读器的内购功能破解

近日,在iPad上购买了PDFExpert阅读器,用于PDF文件的阅读。然而,令人忍无可忍的是在该应用中还有PDF文件的编辑功能不能使用,需要额外付费购买。且研究了两周的ios逆向,迫切需要实战的磨炼,且我的iPad是越狱的,因此想通过tweak插件来修改启用该功能。

本文主要目的是以当前APP的付费功能绕过为主要目的,梳理在iOS应用逆向分析过程中的主要步骤和核心思路,并以此来传播逆向思维。当然,本文所用的工具和技术严谨用于各种非法用途,包括且不仅限于各种黑产、灰产等。

 

一、工具

class-dump:提取可执行文件中的所有头文件
Theos:用于hook代码的开发工具
IDA Pro:用于对可执行文件的反编译分析
Clutch:用于对目标应用进行砸壳
FLEXLoader:用于在设备上分析应用界面元素的工具

 

二、分析过程

1. 定位目标

将iPad的语言切换为英文,便于查找定位相关代码段。首先,打开应用PDFExpert,并随意打开一本PDF文件。在界面顶端工具栏,有Annotate和Edit两个工具按钮,Annotate在购买完应用后即可使用,我们分析的重点在Edit按钮。其界面如下图所示。

随后,点击Edit按钮,弹出如下图所示的界面,提示需要升级。因此,在此做出初步猜测,在点击Edit按钮后,按钮的相应函数中判断当前用户是否已经购买了edit PDF功能,如未购买则提示购买升级;否则,提供对PDF文件的编辑功能。

因此,根据上述做出的初步合理分析和判断,我们需要分析的目标函数为Edit按钮及其响应函数。

2.分析目标

安装FLEXLoader后,在设置中启用对该应用的注入,并重启该应用后在界面中即可看到如下图所示的浮动按钮了。用红色标注的select功能选择Edit按钮后,在views界面查看该按钮的界面元素。

从下图可知,Edit按钮的所属类为RDPDFViewToolbarButton。在FLEXLoader中继续查看该类的详情,发现该类响应UITapGestureRecognizer事件,也即按钮的点击事件。

从下图所示,可知该RDPDFViewToolbarButton接受按钮点击事件,action为tapGesture,target为RDPDFViewToolbarButton类本身。

因此,至此我们从界面UI中确定了我们需要分析的目标函数为RDPDFViewToolbarButton的tapGesture函数,此函数响应Edit按钮的点击事件。

3. 代码分析

从此,开始步入代码分析的阶段。使用clutch对该应用砸壳,并将砸壳后的可执行文件拖入IDA Pro进行解析。经过漫长的等待,IDA终于解析完成,打开目标函数,内容如下。

从中可以确定,tapGesture函数并未做复杂的处理和校验,而是仅仅调用了函数”sendActionsForControlEvents:isApplePencilTouch:”。通过百度搜索,确认该函数的主要作用是将收到的事件Event发送到其他action。
因此,我们需要找到响应该事件的action函数。为此,我们通过cycript注入到PDFExpert进程, 并通过如下的三个步得到目标函数。

  1. cy# [btn allTargets] :返回当前Button所有相关的target对象,此处只有PDFViewMainToolbar一个;
  2. cy# [btn allControlEvents]:获取按钮的所有事件列表,此处只有一个16777216值,即0x0x1000000,对应上文中的”sendActionsForControlEvents:isApplePencilTouch: “函数中的值。
  3. cy# [btn actionsForTarget:#0x14d9f81e0 forControlEvent:16777216]:获取针对某一特定事件目标的全部动作列表。
    因此,通过上述过程,可得知该函数将按钮的点击消息发送给了PDFViewMainToolbar的”contentEditingButtonTouchUpInside:”函数。
    随后,在IDA中打开该函数,其内容如下图所示。调用了[PDFViewMainToolbar delegate]的返回值的”pdfViewMainToolbarContentEditingButtonPressed:”方法。

    为获取该函数所在类,可用cycript注入该APP,上文中我们已经可以获取到PDFViewMainToolbar对象的实例了,随后可直接调用其delegate函数即可得到该目标类,内容如下所示。由此可知,”pdfViewMainToolbarContentEditingButtonPressed:”函数所在类为PDFNewToolbarsController。当然,此处亦可直接在IDA搜索该目标函数,亦可得到该类。

    在IDA中定位到该方法,其内容也很简单,调用了[PDFNewToolbarsController performShowContentEditingToolsWithButton:]函数。

    继续打开[PDFNewToolbarsController performShowContentEditingToolsWithButton:]函数,其内容如下。该函数代码量较多,可以初步确定该位置为核心代码了。很快,我们从Allow关键词即可定位到”toolbarsControllerShouldAllowContentEditButtonAction”函数是我们最终最终关系的核心函数,用于判断是否允许启用Edit按钮的。从返回值的使用上也可以确定,其返回值为BOOL值。

    在IDA中查找函数”toolbarsControllerShouldAllowContentEditButtonAction”,可以确定该函数位于类RDPDFViewController中。至此,我们可以编写Tweak修改该函数的返回值为YES,即可达到启用Edit按钮的目的了。

 

三、Tweak代码编写

上述分析过程中,确定了我们需要hook修改的目标函数为[RDPDFViewController toolbarsControllerShouldAllowContentEditButtonAction],仅需将其返回值设置为YES即可。
相关Tweak代码如下:

%hook RDPDFViewController

- (_Bool)toolbarsControllerShouldAllowContentEditButtonAction{
    return YES;
}

%end

编译安装并重启该应用后,再次点击Edit按钮,很快就弹出了PDF编辑工具栏,已经可以对PDF文件进行编辑操作了,说明我们修改的目标函数很正确。

(完)