简介:此app名称为EasyCost,是笔者目前为止用过的用户界面相对友好的一款记账app,奈何用了很久之后才发现有个所谓的高级功能,咦,看到自动账单这个功能,很高级有木有,鉴于最近才转逆向,于是抱着研究的心态尝试破解,也希望对一些同时刚接触逆向的新手朋友一点点启发。
1.1分析源代码结构,并定位关键函数
1.1.1 首先使用dumpdecrypted砸壳
- 关于dumpdecrypted详细介绍在这里就不再赘述了
- 首先ssh到越狱的手机,单独打开easycost,在终端执行
ps -e
就可以看到当前app的进程名
|
|
因为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()
打印当前的视图层次
这里看到有好多东西,但是仔细一看,有一个KLSwitch,再看到前面“周期记账”的开关是一个UISwitch,于是我们先把注意力放在这个KLSwitch上面。
我们可以先根据这个KLSwitch,先找到他的controller,由于这里的switch是一个对象,而这个界面是一个view,所以我们可以通过nextResponder追溯到它的controller,然后再通过controller来响应这个switch,看看我们的猜想是否正确。
我们在class-dump中的头文件中搜索CatalogInfoViewController.h
找到这个cycleSwitch,猜想这个cycleSwitch应该比较特殊,可能是我们的目标,于是通过之前打印出来的controller来响应这个cycleSwitch,看看究竟会怎样
结果不出意料,在执行了[#0x14d00820 cycleSwitch:YES]
之后,提醒购买的弹框弹了出来,这就初步确定了我们的目标函数
并且也确定了CatalogInfoViewController
这个controller,在接下来的操作中我们将会用到
1.1.4 debugserver+lldb动态调试确认关键函数
接下来该我们该祭起debugserver和lldb了
debugserver运行在iOS上,顾名思义,它作为服务端,实际执行LLDB(作为客户端)传过来的命令,再把执行结果反馈给LLDB,显示给用户,即所谓的“远程调试”。
然后通过命令image list -o -f
查看它的ASLR偏移
我们可以看出它的ASLR偏移为0x0003c000
紧接着我们把之前砸壳的文件拖进hopper或ida,搜索前面得到的CatalogInfoViewController
,大致浏览一遍,可以看到有一个[CatalogInfoViewController cycleSwitch]
这和我们之前的猜想不谋而合
这时候下面的一个isPurchased
(购买)引起了我的注意,我想要看看这个isPurchased到底做了什么事情,究竟是不是我们猜想的那样,于是在函数开始时(0x0004fdf0)打断点,由于之前看到ASLR偏移为0x0003c000,所以要把他们相加才是函数偏移后的地址
进入到函数中后,一直使用ni
命令,直到函数到这里
打印r0,发现参数为nil,我们来尝试着把r0的值改为1,然后我们发现这时候就可以使用我们的所谓“周期记账”的高级功能了,当然这还没完,现在这里只是确定目标函数以及参数,接下来我们就开始最关键也最必不可少的一步,就是用theos来编写tweak
1.2编写tweak
我们首先在导出的头文件中查找isPurchased,找到Purchased.h文件
然后我们看到@property(nonatomic,getter=isPurchased,setter=setPurchased:) BOOL purchased,我们把这个purchased永久返回1,应该就可以完成我们的任务了。
继续,新建工程,编辑makefil
然后继续编辑tweak
打包编译安装到越狱手机,就可以看到我们可以使用所谓的高级功能了。
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开发,没有官方文档作为参考,最有效的方式就是不断尝试,不断犯错,再不断改进,我们面对的总是一些未知的东西,或许你离成功只差一步,但却因为看不到前方,而走向一条更困难的路,我们在计算机的行业里只有不断探索,才有可能逐渐超越自我,小弟也是初学逆向,对自己说也对路上的朋友说,愿我们在探索的道路上一直勇敢下去。