某记账app内购破解

简介:此app名称为EasyCost,是笔者目前为止用过的用户界面相对友好的一款记账app,奈何用了很久之后才发现有个所谓的高级功能,咦,看到自动账单这个功能,很高级有木有,鉴于最近才转逆向,于是抱着研究的心态尝试破解,也希望对一些同时刚接触逆向的新手朋友一点点启发。

IMG_2811.PNG

1.1分析源代码结构,并定位关键函数

1.1.1 首先使用dumpdecrypted砸壳

  • 关于dumpdecrypted详细介绍在这里就不再赘述了
  • 首先ssh到越狱的手机,单独打开easycost,在终端执行ps -e 就可以看到当前app的进程名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
linguochengde-iPhone:~ root# ps -e
PID TTY TIME CMD
1 ?? 0:09.72 /sbin/launchd
18 ?? 0:00.03 /usr/libexec/amfid
27 ?? 0:11.42 /usr/sbin/syslogd -bsd_out 1
...
1006 ?? 0:00.34 /System/Library/Frameworks/UIKit.framework/Support/pasteboardd
1102 ?? 0:02.93 /var/mobile/Containers/Bundle/Application/7E51DAF5-3FCF-42CF-B4CB-F47CC4078048/easycost.app/easycost
1219 ?? 0:00.00 (bash)
1220 ?? 0:00.28 (gssc)
770 ttys000 0:00.06 -sh
810 ttys000 0:00.30 cycript
1221 ttys000 0:00.01 ps -e

因为iOS上只打开了一个AppStore中的app,所以唯一的那个含有/var/mobile/Containers/Bundle/Application/字样的结果就是目标可执行文件的全路径。

Cycript -p 1102

1.1.2 class-dump获取.h头文件

  • 在砸壳后文件的目录下,我们执行class-dump --arch armv7 -S -s -H 可执行文件 -o 自定义的文件夹路径,获得砸壳后的头文件

1.1.3cycript打印视图层次

Cycript是由saurik推出的一款脚本语言,更多资详细资料可以查看它的官网http://www.cycript.org ,可以从MTerminal中执行Cycript,也可以ssh到ios设备中执行Cycript

我们首先根据之前介绍的方法向目标app注入Cycript

紧接着我们找到这个付费功能具体实现的界面,也就是在“周期记账”选项所在的界面中,输入

UIApp.keyWindow.recursiveDescription().toString()打印当前的视图层次

FCEB9BAB-CD0C-43D4-B426-D06C898173B3.png

F9450BEC-1327-422A-ABB2-329261226707.png

这里看到有好多东西,但是仔细一看,有一个KLSwitch,再看到前面“周期记账”的开关是一个UISwitch,于是我们先把注意力放在这个KLSwitch上面。

我们可以先根据这个KLSwitch,先找到他的controller,由于这里的switch是一个对象,而这个界面是一个view,所以我们可以通过nextResponder追溯到它的controller,然后再通过controller来响应这个switch,看看我们的猜想是否正确。

我们在class-dump中的头文件中搜索CatalogInfoViewController.h

9C4A794D-EA81-48A9-9CCC-B35A4732E574.png

找到这个cycleSwitch,猜想这个cycleSwitch应该比较特殊,可能是我们的目标,于是通过之前打印出来的controller来响应这个cycleSwitch,看看究竟会怎样

45C6EDA8-9524-40C6-AA3E-B30F13FF2595.png

结果不出意料,在执行了[#0x14d00820 cycleSwitch:YES]之后,提醒购买的弹框弹了出来,这就初步确定了我们的目标函数

并且也确定了CatalogInfoViewController这个controller,在接下来的操作中我们将会用到

0968E158-257D-4297-9079-4E791557F421.png

1.1.4 debugserver+lldb动态调试确认关键函数

接下来该我们该祭起debugserver和lldb了

debugserver运行在iOS上,顾名思义,它作为服务端,实际执行LLDB(作为客户端)传过来的命令,再把执行结果反馈给LLDB,显示给用户,即所谓的“远程调试”。

D107C0B6-4633-459D-8B45-9235708A3C43.png

A5D1E3ED-594C-443C-B2B5-92CE6F6FF86D.png

然后通过命令image list -o -f 查看它的ASLR偏移

2B333515-BCE0-4FC8-90A8-669D05F9E078.png

我们可以看出它的ASLR偏移为0x0003c000

紧接着我们把之前砸壳的文件拖进hopper或ida,搜索前面得到的CatalogInfoViewController ,大致浏览一遍,可以看到有一个[CatalogInfoViewController cycleSwitch]这和我们之前的猜想不谋而合

33975B1D-E93E-4299-BC26-2A7CAB3E91C6.png

这时候下面的一个isPurchased (购买)引起了我的注意,我想要看看这个isPurchased到底做了什么事情,究竟是不是我们猜想的那样,于是在函数开始时(0x0004fdf0)打断点,由于之前看到ASLR偏移为0x0003c000,所以要把他们相加才是函数偏移后的地址

ECAB072D-B5A4-49C6-AB59-BCA32DB944D0.png

进入到函数中后,一直使用ni命令,直到函数到这里

A9D9E77F-064B-412F-AC02-0B51AB3C0FC2.png

打印r0,发现参数为nil,我们来尝试着把r0的值改为1,然后我们发现这时候就可以使用我们的所谓“周期记账”的高级功能了,当然这还没完,现在这里只是确定目标函数以及参数,接下来我们就开始最关键也最必不可少的一步,就是用theos来编写tweak

1506AF86-8E46-4436-9969-08F0A8432331.png

1.2编写tweak

我们首先在导出的头文件中查找isPurchased,找到Purchased.h文件

BBC752AF-F902-48FD-8911-290F35A0A589.png

0294818F-275B-43E2-ABA8-D8CA789D0754.png

然后我们看到@property(nonatomic,getter=isPurchased,setter=setPurchased:) BOOL purchased,我们把这个purchased永久返回1,应该就可以完成我们的任务了。

继续,新建工程,编辑makefil

QQ20161118-1@2x.png

然后继续编辑tweak

QQ20161118-2@2x.png

QQ20161118-3@2x.png

打包编译安装到越狱手机,就可以看到我们可以使用所谓的高级功能了。

2.0关于防护措施杂谈

俗话说得好,有攻就有防,ios安全防护措施虽说没有安卓这么多,但也有逐渐发展的趋势,小弟觉得首先一个原因可能是国内代码混淆技术没有普及,而且大多数app也只有核心功能才会被混淆,不然全文混淆的话运行过程中的内存加解密也是很大的开销。

关于防护措施,较为普遍的就是引入动态防护组件,个人觉得x维安全相对做的还不错,就目前来说绝大多数app连基本的反调试功能都没有,引入动态防护组件,可以一定程度上防止动态注入、动态调试,方法名类名混淆等,还有关于llvm的一些东西,如在IR层实现一些混淆逻辑,加入各种跳转各种无用逻辑但又不会影响原有的程序逻辑,具体可以参考https://github.com/obfuscator-llvm/obfuscator/,不过挺久没维护了需要自己大动干戈折腾一番,对个人能力要求较高,而且IR层的混淆本身问题较多可能使app存在很多潜在的bug,并且在一定程度上可以被还原,所以只要能做到以上的一些,可以防止新手逆向,在一定程度上已经把很多人挡在了外面。ps:黑灰产朋友应该感谢微信没做防护措施。

除了这些当然还有其他方面的防护措施,随着计算机的发展安全也会越来越被重视,对ios逆向感兴趣推荐@大名狗剩的《ios应用逆向工程》以及论坛bbs.iosre.com,欢迎前来交流。

小结:本文为这款记账软件制作了去除高级功能限制插件,让我们可以更全面的使用这款app,虽然最后的代码只有几行,但整个分析过程却是一环扣一环,哪怕其中一环出错不注意就会被误导,逆向这款app虽然说挺简单的,但主要思路差不多都是这样,希望能为正在学习并且自己对心仪的app无从下手的朋友提供一些帮助。

有些朋友觉得本文运气成分很大,没错,逆向工程不比app开发,没有官方文档作为参考,最有效的方式就是不断尝试,不断犯错,再不断改进,我们面对的总是一些未知的东西,或许你离成功只差一步,但却因为看不到前方,而走向一条更困难的路,我们在计算机的行业里只有不断探索,才有可能逐渐超越自我,小弟也是初学逆向,对自己说也对路上的朋友说,愿我们在探索的道路上一直勇敢下去。

文章目录
  1. 1. 1.1分析源代码结构,并定位关键函数
    1. 1.1. 1.1.1 首先使用dumpdecrypted砸壳
    2. 1.2. 1.1.2 class-dump获取.h头文件
    3. 1.3. 1.1.3cycript打印视图层次
    4. 1.4. 1.1.4 debugserver+lldb动态调试确认关键函数
  2. 2. 1.2编写tweak
  3. 3. 2.0关于防护措施杂谈
|