近日,在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进程, 并通过如下的三个步得到目标函数。
- cy# [btn allTargets] :返回当前Button所有相关的target对象,此处只有PDFViewMainToolbar一个;
- cy# [btn allControlEvents]:获取按钮的所有事件列表,此处只有一个16777216值,即0x0x1000000,对应上文中的”sendActionsForControlEvents:isApplePencilTouch: “函数中的值。
- 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文件进行编辑操作了,说明我们修改的目标函数很正确。