背景
逆向工程相对于正向的开发,或许重视的没有那么高,尤其是比较于安卓或许其他平台,苹果的安全机制更严厉,逆向的流程也会更繁琐,除了有ASLR(地址空间布局随机化),还有FairPlay DRM的iPA加密办法,也便是咱们俗称的壳。这个给逆向作业带来了更多的挑战。可是更好更安全的加密办法也仅仅增加破解的本钱,并不是绝对的安全
,这也是逆向的前提。
最近也正在做一些调研的作业,需求从技能层面去剖析其他App的一些底层逻辑,要用到iOS的逆向相关的技能,可是由于笔者做这些作业的时分正处于MacOS、iOS、Xcode三个体系的大版本更新期间,一些体系的运转办法和逻辑发生变化,所以导致网上能找到的材料根本都失效了,所以写文档记录下。
前置作业
环境
- Mac架构: Intel架构
- MacOS: 13.0.1 (22A400)
- Xcode版本:Version 14.1 (14B47b)
- iOS体系版本:iOS 16.0
相关东西
-
MachOView
- 用来查看Mach-o的文件结构,以及各个部分的信息
-
class-dump
- class-dump,望文生义,便是用来dump方针对象 的class信息的东西。它利用Objective-C言语的runtime 特性,将存储在Mach-O文件中的头文件信息提取出 来,并生成对应的.h文件。
-
MonkeyDev
- 非越狱开发插件,能够进行动态库注入,hook相关操作
-
Hopper Disassembler
- Hopper Disassembler是Mac上的一款二进制反汇编器,根本上满足了作业上的反汇编的需求,包含伪代码以及操控流图(Control Flow Graph),支撑ARM指令集并针对Objective-C的做了优化。
iPa下载
iOS App的逆向的一切操作都是依据iPa的操作,所以大前提是要有方针iPa,这儿供给三种办法来进行iPa下载,大家能够挑选合适自己的办法下载。
办法1:三方运用商场
现在这样的运用商场比较多,多是平替iTunes的一些软件
- 爱思帮手
- iTools
运用如上的三方软件能够很快的下载对应的ipa包,可是由于上述商场都是镜像自AppStore的内容,并且自己重签名,所以更新的及时性或许没有那么快,也没有那么全,并且由于是被第三方进行了修正重签,所以内容也不一定保证和官方的共同。假如不在乎这些的话还是能够采取这类的办法下载。
办法2:Apple Configuration
能够直接从Mac 上的Apple Store上下载,官方出品,原本是给手机上装置app的。用此办法其实是利用了该App的App下载机制来进行ipa导出的
挑选增加App,然后在弹出的弹窗中挑选App并且下载
这个时分假如你手机上没有装置该App,则直接会装置成功,此刻咱们再点击装置下载,然后就会收到设备上现已存在相同的App,是否掩盖装置的提示
的弹窗,此刻咱们不要理会这个弹窗。
然后到如下途径就能够取到对应的ipa
~/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps/
办法3 DumpApp
是一个第三的网站,同在线砸壳+ipa下载的服务,由于咱们最终想要的便是一个砸壳之后的ipa,所以这个网站直接帮咱们做好了,只不过是收费的,每个app是9元,可是有多个境外的App商场,比较全面。
iPa砸壳
假如iPa的获取办法挑选办法3,则能够略过砸壳步骤
app 上传到AppStore后 苹果运用 fairplay DRM来加密,便是咱们所说的壳DRM全称Digital Rights Management,即数字版权维护。苹果为了维护App Store分发的音乐/视频/书籍/App免于盗版,开发了Fairplay DRM技能。
一切逆向都是建立在砸壳的前提下,砸壳的办法有两种:
静态砸壳
便是不依赖程序运转,直接用ipa包就能够进行砸壳解密,比方说我现已知道了他的加密算法,或许我通过暴力破解了他的加密算法,然后对ipa进行解密,可是这样的办法难度较大,并且假如人家一旦换了加密办法或许有其他的改动,那解密办法就不收效了,常见的静态砸壳东西有以下
- [fouldecrypt](NyaMisty/fouldecrypt: A lightweight and simpling iOS binary decryptor (github.com))
- Iridium
动态砸壳
与静态相反,动态砸壳便是依赖运转时的原理来进行解密,不过与其说是解密,倒不如说是内存提取,由于不管ipa包用什么加密办法,最终都是解密后运转到内存里边的,所以咱们能够以为一个ipa在内存上的数据是未加密的
,所以此刻咱们只要把内存上的数据提取出来即可,整个进程也不涉及到解密操作,及时后边Apple更换加密办法,也不影响动态砸壳的进程。
动态砸壳的办法和东西有很多,现在根本现已流水线化了,能够运用以下办法和东西来进行处理,前提是要有一个越狱的手机。
-
dumpdecrypted
-
Clutch
作用查验
砸壳后需求查看是否砸壳成功,找到对应砸壳后的的ipa,点进去找到mach-o文件,履行如下指令,然后在输出查看cryptid
字段假如为0
就说明砸壳成功。XXX = mach-o姓名
otool -l XXXXX |grep cry
头文件导出
砸壳后的的第一步便是将ipa文件的头.h文件导出,然后依据 头文件的办法和特色进行逆向剖析,在找到对应的hook点。一般咱们运用class-dump,能够去他的官网下载对应的文件,然后将文件拷贝到对应的目录下。
sudo cp class-dump /usr/local/bin
这一步没什么问题,拷贝完结重启终端就能够调用class-dump的办法了.
导出
履行下面的指令,导出头文件,需求留意的是:导出后会有上万个个文件,所以方针目录最好不要选Desktop或许其他的根目录
class-dump -S -s -H XXXXX -o /path/to/headers/
有的时分会收到这样的过错
Error:Cannot find offset for address 0xd80000000101534a in stringAtAddress:
这是由于项目运用了Oc和Swift的混编,需求赋予class-dump文件权限即可
sudo chmod 777 /usr/local/bin/class-dump
之后就能够导出成功了。
MonkeyDev
这是一个为越狱和非越狱开发人员预备的东西,主要包含四个模块:
-
Logos Tweak
-
运用theos供给的
logify.pl
东西将*.xm
文件转成*.mm
文件进行编译,集成了CydiaSubstrate
,能够运用MSHookMessageEx
和MSHookFunction
来Hook
OC函数和指定地址。
-
-
CaptainHook Tweak
-
运用CaptainHook供给的头文件进行OC 函数的Hook以及特色的获取。
-
-
Command-line Tool
-
能够直接创立运转于越狱设备的指令行东西
-
-
MonkeyApp
- 这是主动给第三方运用集成Reveal、Cycript和注入dylib的模块,支撑调试dylib和第三方运用,支撑Pod给第三放运用集成SDK,只需求预备一个砸壳后的ipa或许app文件即可。
装置
Monkeydev依赖Theos.Theos是一个越狱开发东西包,由iOS越狱界知名人士 Dustin Howett 开发并分享到 GitHub 上。Theos 与其他越狱开发东西比较,最大特色便是简略:下载装置简略、Logos语法简略、编译发布简略,能够让运用者将精力都放在开发作业上去。
装置Thoes
sudo git clone --recursive https://github.com/theos/theos.git /opt/theos
装置Monkeydev
sudo /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/AloneMonkey/MonkeyDev/master/bin/md-install)"
卸载Monkeydev
sudo /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/AloneMonkey/MonkeyDev/master/bin/md-uninstall)"
更新Monkeydev
sudo /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/AloneMonkey/MonkeyDev/master/bin/md-update)"
装置问题
在装置进程中,修正用户 profile
文件时,找不到 MacOSX Package Types.xcspec
和 MacOSX Product Types.xcspec
文件
File /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Package Types.xcspec not found
这个是由于最新的Xcode14中 这个途径现已改变,所以原途径无法找到,不过假如大家需求逆向的事iOS的App到这一步能够不用关怀,这个是MacOS相关的模板文件。此刻翻开Xcode假如有以下模版文件,并能成功创立工程即可。
编译报错
通过上一步的模板文件创立好工程后,直接真机编译运转,这个时分会提示编译过错
iOS file not found: /usr/lib/libstdc++.dylib
这是由于Xcode 10
之后删去的libstdc++
库。能够参考此解决方案。之后就能够编译成功了,并且手机上能够跑起来。
第二个过错是Fishhook中的过错,这个是是由于Fishhook用的是比较老的版本,自身存在bug,只要去github官网找到fishhook最新代码 copy过来即可。
文件结构
文件结构如下如图
这是一个规范的MonkeyDemo的结构
-
TargetApp
:放方针ipa
的文件,将需求逆向的破壳ipa
放在此处 -
Logos
:编写相关hook
的文件,一切hook
操作在此处,可是由于该文件下要用了logos句子,有一定的学习本钱,所以后边的hook函数能够直接写在上面的MonkeyDeomDyLib.m中 -
fishhook
:用来hook
体系函数的库
上方的MonkeyDeomDyLib便是咱们行将注入进去的动态库。
动态库注入
运转demo后动态库注入成功,操控台会有如下输出
!!!congratulations!!!\n----------------insert dylib success----------------
可是假如是和我相同的运转环境,你是大概率看不到的,由于会注入失利。这儿尝试了两种办法
- insert_dylib 同样注入失利,
- optool 注入成功
下面说下optool运用
-
下载编译optool
git clone https://github.com/alexzielenski/optool.git cd optool git submodule update --init --recursive
-
找到编译产品
-
把编译产品拷贝到
/opt/MonkeyDev/bin
下 -
修正
/opt/MonkeyDev/Tools/pack.sh
顶部刺进 OPTOOL="${MONKEYDEV_PATH}/bin/optool" 同上面相同 修正刺进动态库东西代码 "$OPTOOL" install -c load -p "@executable_path/Frameworks/lib""${TARGET_NAME}""Dylib.dylib" -t "${BUILD_APP_PATH}/${APP_BINARY}"
-
然后保存从头运转即可注入成功
pod运用
在调试App时分咱们会用到类似lookIn或许FLEX的等东西来看App 的层级结构和 沙盒文件,同样需求pod来接入。
-
像平常创立podfile文件相同 进入到工程目录
pod init
-
在生成的podfile中增加pod,可是要留意是在DemoLib的trarget中增加,由于咱们的pod是打入动态库的,然后由动态库带入App
# Uncomment the next line to define a global platform for your project # platform :ios, '9.0' target 'Demo' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! end target 'DemoDylib' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! pod 'FLEX' pod 'LookinServer' end
-
然后
pod install
即可看到作用
代码Hook
通过Lookin 咱们能够找到下手点和对应的类名,然后通过之前导出的头文件能够查看类名对应的函数,接下来便是要看下函数里边做了哪些工作,就要用到Hook手段,MonkeyDev给咱们封装好了Hook相关的办法,包含OC和C的Hook函数
-
CHDeclareClass
注册类名。也便是注册要被hook的函数地点的类,比方
CHDeclareClass(MYViewController)
-
CHOptimizedMethod1
hook实例办法,你会发现后边跟了数字1~10,代表被hook 的函数的参数的个数,比方我即将hook的函数只要一个参数 那么就运用CHOptimizedMethod1参数含义为
-
第一个参数,一般传self
-
第二个参数,传返回值类型,没有返回值便是void
-
第三个参数,函数地点的类名
-
第四个参数,办法名
-
第五个参数,函数参数的类型
-
第六个参数,函数参数的变量
其中第五第六个参数在CHOptimizedMethod1
10 中会重复110次CHOptimizedMethod1(self, void, MYViewController, appMethod, id, para) { NSLog(@"appMethod被Hook = %@", para); }
-
-
CHOptimizedClassMethod3
hook类办法,一切函数定义同上
-
CHConstructor结构
用来注册刚才的hook操作
CHConstructor{ // 注册即将hook的类 CHLoadLateClass(MYViewController); // 注册即将hook 的办法 CHHook1(MYViewController, appMethod); }
上面流程履行完结后就能够看到函数被Hook了
Hopper Disassembler
上面的步骤讲了怎么通过lookin或许reveal等东西来定位类名,然后通过类名在头文件中找到函数名,然后通过hook手段来改变函数的一些表现,可是在怎么没有拿到.m文件的前提下看到某个函数的实现呢?比方一个函数中都做了哪些操作,调用了哪些其他函数,以及调用链是怎样的?
这个时分就需求用到Hopper Disassembler
或许IDA Pro
这样的东西了,不过现在遇到的困难是在笔者的体系环境下,这两个软件的破解版无法装置,并且IDA Pro
的官方试用版还不支撑Arm的汇编,所以只能运用Hopper Disassembler来举比如。翻开软件,将对应App 的Mach-o
文件拖入Hopper中等候它剖析完结
处理完后的界面左面会显现办法名,支撑查找查询,中间区域显现的是汇编代码,咱们查找一个在之前dump出的头文件中的一个函数名试下。
[XXXXXXXX listenerDownloadLyricWithSongId:resultBlock:]
能够看到中间的部分显现出来函数所对应的汇编代码
然后按快捷键Option+enter
即可转为伪OC代码,尽管包含一些的寄存器信息,可是也足以剖析了。一起双击能够跳转到对应的函数内部。
最终
以上便是现在的逆向调研进程,这儿先记录下,后边还会深入研究,有新的发现会同步更新此文章。