对iOS某音乐App的逆向

最近学习了《ios应用逆向工程》,和刚开始学习《ios应用逆向与安全》,也请教了一些前辈大佬们,结合自己已有的编码基础,于是尝试分析了某ios上的音乐app,写了一遍关于入门做ios小功能性插件的心得,希望分享,希望可以促进ios开发,与安全研究。
实现功能:
普通vip音乐随意品质下载与试听。
分析链接如下:
https://medium.com/@tougbao/ios逆向分析初探-9d4ec60e4b86
开发的deb已上传bigboss,待审核通过。
插件功能:
1.普通用户普通vip音乐随意品质下载与试听。
2.绿钻vip用户壳免费试听下载所有歌曲包括下架歌曲和数字专辑。


1. 撰写本文的原因

笔者作为一名能搬砖的人,再较为系统性学习了计算机基础知识,和一些语言的编程基础后,通过学习《ios应用逆向工程》这本书学会了如何通过theos开发插件,并进行动态调试程序,和静态分析,掌握了如何去开发一款自己的ios越狱的插件,也学到了一些代码安全防范知识,而我在分析app的时候也总结出了一些经验,希望与志同道合的人分享。希望能小促进一下ios安全开发

2.什么是通过MVC方式分析?

MVC方式就是直接依靠app类名的规则定位到具体函数,移动端app的架构大多都是MVC的架构形式,由View层,Controller层,Model层组成。View和Model不能直接通信,必须通过Controller层通信,View层即是用户看到的一些控件,《ios应用逆向工程》书中已经详细教学了如何通过Cycript注入进行动态调试,例如通过对象指针调用nextresponder的方法进行从view层到controller层再到model的转移,这是一个很有效的的方法。但是,很多情况下并不需要关心view层和controller层,因为如果仅是想测重要数据的安全性,那么可以直接看向model层,观察其数据模型,进行hook修改尝试。

区分依据在于app 工程类项目的开发,类名,方法名都是有一定规律的,可通过类名,方法名筛选model。当然如果是想增加什么空间,或者祛除一些app的顽固广告的话,应该筛选controller,只要阻断消息传递就行,之后会有例子解释这些,因为如此,在我看来,有某些情况,直接从MVC的架构直接定位函数效率较高。

3.工具介绍

1.class-dump

解析ios二进制文件导出接口头文件的工具

2. Monkeydev

一款非常好用的xcode集成工具,集成了theos功能,并可以签名安装第三方app到自己手机进行动态调试。

3. theos

编译ios deb插件的app,无需多言。

4. flex(不必须)

一款好用的ios插件,相当于class-dump的手机版,并可以在其中置空,改写基本方法类型返回值,相当于简单插件整合器。

4.实战分享

逆向某app当前最新版。

1. 需求

1.试听任何品质的付费音乐

  1. 下载任何品质的付费音乐

  2. 可随意使用dts模式

2.实现步骤

1.验证可行性

下载安装app,登陆账号,进去随便放一首歌,可以免费听标准品质但切换SQ品质时会跳到这个页面,因为我不是vip用户


然后就想,这个购买页面应该是H5,是一个从服务器端过来的网页,因为yi已经判断我不是vip用户,当我点切换品质按钮时并没有切换品质,而是触发该事件的跳转,那么如果我开启手机的飞行模式,又会有什么结果呢?

结果跳转的是这个页面,批量下载加入到下载栏,是

那么,可以得出结论,vip判断存在一部分的本地逻辑,如果hook这些会有什么结果?

从某助手上下载最新版的ipa包,(appstore壳懒得自己处理了),提醒一下,某些版本的该app多一个壳,clss-dump没办法hook,详细https://everettjf.github.io/2015/12/28/simple-ios-antidebugging-and-antiantidebugging/ 这里有处理方法,
通过class-dump 解开,

自然比较大的项目必然一堆的接口文件,这里就可以用到mvc的思想分析了,控件的类就属于view层,只是显示作用,改了对我们的需求也没什么用,,controller是控制view的,改了最多能不跳付费页面,可真正控制的是model层,所以先找几个文件名看得懂英文的打开看看,分析发现,某音乐app的view层基本都含大V,这些类文件就可以不管了,而controller文件都带有controller,都很有规律(一般大公司开发,这些都很规范),然后把原来文件名带有view,controller删了,再分析那些是model层的类文件,发现model层的文件都是直接英文命名的,还能排除一些抽象类文件,找其中其中的实现类,尤其是我们想知道的song信息,download信息,都是直接songinfo,downloadinfo;
image

我们先看downloadinfo,
image

发现这是一个重要的具体实现类,他的超类是downloadBasicInfo,算是抽象类,没东西,而在这个具体的实现类中的数据模型里存在疑似我们想要的信息,havedownloadright,havecheckdownloadright,那么是不是改了就成功了?最起码可以下载了?把这两个方法肯定是保留的, 然后,为了进一步验证我们的猜想,我们就要用到flex了,临时做一个小插件看看,进入flex解包,然后搜索

havedownloadright,havecheckdownloadright,再勾选,

image

image

接着打上临时补丁之后打开某音乐app验证,毫无疑问,vip跳转还在,随便试试发现,批量下载一个标准品质的付费音乐,
image

惊喜,可以下载下来了看来这两个方法就是我们必不可少的方法,接着我们想我们回看dongloadinfo类,看看还有没有我们需要的好东西,我们注意到了这个品质的方法,

猜想:是不是返回值不同数字就是不同品质?

我们试试,通过下载允许下载的免费音乐,例如薛之谦的尝试,

尝试的结果,如果return 0;则是普通音质图略

如果是renturn 1,则是HQ音质,

如果 return 2,则是强制SQ,

于是我们把这句加上,是不是能下载SQ音质的音乐呢?


发现失败了,然后又瞎猜,把关于right的都加上,发现没用,那我们去查一查日志,日志存在于download里的ilog文件夹里,发现都是.xlog格式的,打不开,应该加密的。。。没办法,于是,我尝试安装7.x版本的app看看日志,这回能看了,


发现请求歌曲信息的构成是有一个vkey的,而下载不了,或者播放失败这里应该是空,把歌曲的url+vkey组合放到某雷里也能下载歌曲。到这里几乎要放弃了,但是这时,该app提醒要不要下载下载历史里的音乐,随意选几首,下载成功了,那么,我就已经可以得出逻辑了,一般付费歌曲,普通用户可以听标准音质,但听标准的同时vkey已经拿到,记录在下载历史中,然后再次通过quality控制品质,就能下载各种音乐,也就是说能听的音乐都能下载,而去听的本质也是要调用下载的相关方法的,不然到不了手机里呀,那么我们是不是设想一个场景,我打开app,随意选了一首歌,然后播放完,点下载或者点切高品质,就能调用downloadhistory里的通道下载?不需要对quality切来切去的?

我们继续分析,

看看阻挡我按vip按钮的到底在哪;

downloadinfo已经被我们分析完毕了,我们再检查songinfo,看看歌曲的model是什么样的?
image

一堆的bool值,但似乎都是我们不感兴趣的信息;

直到看到这里,顿时我起了疑心,isenablexxxx什么的如果是我写代码那么用个int或者bool就行了,怎么会需要定义一个复杂类型SFlexInteger?为什么要多此一举做这个封装?我不知道这个结构体的具体构造,毕竟初学,我请教了逆向大佬@CodeTips,得知class-dump通常把奇怪的结构类型放在CDStructures.h里面,
image

这样的结构,分析到这里,要去创建项目了,打开monkeydev创建一个app项目(手机没越狱),改写相关SFlexInteger类型的方法,
image

设置断点调试,发现
t.date=0; 两个char是16进制,显然存的某个地址,而data域则应该就是标识位,全部置1,再次调试,发现奇迹发生了,播放界面已经判断我是vip了,



本地vip权限已经解开了,之后在把调用downloadhistory端口的方法写入播放事件,写入正常下载事件就好,做到只要能免费听的歌曲,获取其vkey可以,(该app的后端数据库应该不是太合理,歌曲的分类不明确,有点复杂)这里省略。

5.总结:

由此可见掌握MVC的思维去分析app还是很重要的,《ios应用逆向工程》的作者沙梓社有这么一段话我非常赞同,触动了我的心灵,………当我们站在高处,在天空鸟瞰这个app所在的城堡,它的内部就不再是秘密,这时,所有的oc函数定义,数据模型,变量完全暴露在我们面前,城墙的防护意义荡然无存。处于这个维度,城墙已经不再是阻碍,我们更应该关注是如何从偌大的城堡的前提下,选择任意高维度地点进入低纬度的城堡,巧取而不豪夺,通过监视改变app的运行逻辑,从而达到获取核心信息,了解软件设计原理等战术目的。

参考文献:《ios应用逆向工程》,《ios应用逆向与安全》

感谢@CodeTips@百岁老人@泠风阿的热心帮助。

3 个赞

mark~!!

bigboss的管理者拒绝了我的tweak,解释说以前允许的,现在不允许这种插件,:sweat:

放到github不就好了

我这边ios11 安装了闪退 最新版本 7.X版本都试了

默认 17:38:24.377800 +0800 QQMusic TweakInject: Loading for binary QQMusic
默认 17:38:24.627914 +0800 QQMusic Injecting /Library/TweakInject/AudioRecorderStatusBar.dylib
默认 17:38:24.633208 +0800 QQMusic Injecting /Library/TweakInject/FLEX.dylib
默认 17:38:24.635757 +0800 QQMusic Injecting /Library/TweakInject/Flex.dylib
默认 17:38:24.649079 +0800 QQMusic Checking for file at /var/mobile/Containers/Data/Application/4D25D2DA-3F5A-40AF-AFF4-299BB83F466F/Library/Caches/flex-extract.signal
默认 17:38:24.649404 +0800 QQMusic Checking for file at /var/mobile/Containers/Data/Application/4D25D2DA-3F5A-40AF-AFF4-299BB83F466F/Library/Caches/flex-extract.signal
默认 17:38:24.660783 +0800 QQMusic FLXX: Loaded patches from: /var/mobile/Library/Application Support/Flex3/patches.plist
默认 17:38:24.664208 +0800 QQMusic Injecting /Library/TweakInject/FLEXible.dylib
默认 17:38:24.668097 +0800 QQMusic Injecting /Library/TweakInject/GPSCheat.dylib
错误 17:38:24.670243 +0800 QQMusic libsubstrate-shim: Tried to hook non-existent selector onClientEventLocation: on class CLLocationManager
默认 17:38:24.670341 +0800 QQMusic Injecting /Library/TweakInject/InApp.dylib
默认 17:38:24.670596 +0800 QQMusic Injecting /Library/TweakInject/QQMusicProjectDeb.dylib
错误 17:38:24.778549 +0800 QQMusic libsubstrate-shim: Tried to hook non-existent selector isSAerverGraySongByAssetsType: on class SongInfo
错误 17:38:24.778790 +0800 QQMusic libsubstrate-shim: Tried to hook non-existent selector isEnableAddToByAssetsTyoe: on class SongInfo
错误 17:38:24.778911 +0800 QQMusic libsubstrate-shim: Tried to hook non-existent selector inEnableSingSongByAssetsType: on class SongInfo
错误 17:38:24.779017 +0800 QQMusic libsubstrate-shim: Tried to hook non-existent selector isVIPDownloadSong on class SongInfo
错误 17:38:24.779106 +0800 QQMusic libsubstrate-shim: Tried to hook non-existent selector canDownloadAAfterCacheAssetsType:songRate: on class SongInfo

你是不是electra越狱?那个越狱装了会闪退,感觉是cydiasubstrate的问题,我在解决中,目前还不知道方法解决。

en 对的 就是electra越狱

medium在国内被X了,你把内容直接发到论坛里?

直接放到帖子里?可以的,等下我去改一下,或者写一个md文件,主要感觉是不是这类内容放内网是不是不太合适?:sweat:

没关系,你先发吧,把App名字给隐去就可以了;然后我再看看,帮你编辑一下

好,行的。

好了,我把原文移到帖子上了,麻烦大佬审查一下。

1 个赞

思路清晰。挺好的。

把代码也分享到github呗,学习下

抱歉,由于该插件存在争议性,不打算公布源码,而且重点是我分享的这个开发思想。:grinning_face_with_smiling_eyes:

不太稳,下载失败概率大,播放自动跳转到标准

你必须等标准品质的缓存完,或者把边听边存打开,或者尝试点下载按钮。

感谢分享,要先下载标准普通的品质,才能下载后面的高品质。逆向最新版的很不容易

Github地址已经没有了~