背景

逆向工程相对于正向的开发,或许重视的没有那么高,尤其是比较于安卓或许其他平台,苹果的安全机制更严厉,逆向的流程也会更繁琐,除了有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导出的

iPa逆向之路

挑选增加App,然后在弹出的弹窗中挑选App并且下载

iPa逆向之路

这个时分假如你手机上没有装置该App,则直接会装置成功,此刻咱们再点击装置下载,然后就会收到设备上现已存在相同的App,是否掩盖装置的提示的弹窗,此刻咱们不要理会这个弹窗。

iPa逆向之路

然后到如下途径就能够取到对应的ipa

~/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps/

办法3 DumpApp

是一个第三的网站,同在线砸壳+ipa下载的服务,由于咱们最终想要的便是一个砸壳之后的ipa,所以这个网站直接帮咱们做好了,只不过是收费的,每个app是9元,可是有多个境外的App商场,比较全面。

iPa逆向之路

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逆向之路

头文件导出

砸壳后的的第一步便是将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,能够运用MSHookMessageExMSHookFunctionHook 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.xcspecMacOSX 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假如有以下模版文件,并能成功创立工程即可。

iPa逆向之路

编译报错

通过上一步的模板文件创立好工程后,直接真机编译运转,这个时分会提示编译过错

iOS file not found: /usr/lib/libstdc++.dylib

这是由于Xcode 10之后删去的libstdc++库。能够参考此解决方案。之后就能够编译成功了,并且手机上能够跑起来。

第二个过错是Fishhook中的过错,这个是是由于Fishhook用的是比较老的版本,自身存在bug,只要去github官网找到fishhook最新代码 copy过来即可。

文件结构

文件结构如下如图

iPa逆向之路

这是一个规范的MonkeyDemo的结构

  • TargetApp:放方针ipa的文件,将需求逆向的破壳ipa放在此处

  • Logos:编写相关hook的文件,一切hook操作在此处,可是由于该文件下要用了logos句子,有一定的学习本钱,所以后边的hook函数能够直接写在上面的MonkeyDeomDyLib.m中

  • fishhook:用来hook体系函数的库

上方的MonkeyDeomDyLib便是咱们行将注入进去的动态库。

动态库注入

运转demo后动态库注入成功,操控台会有如下输出

iPa逆向之路

               !!!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
    
  • 找到编译产品

    iPa逆向之路

  • 把编译产品拷贝到/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 即可看到作用

    iPa逆向之路

代码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中等候它剖析完结

iPa逆向之路

处理完后的界面左面会显现办法名,支撑查找查询,中间区域显现的是汇编代码,咱们查找一个在之前dump出的头文件中的一个函数名试下。

[XXXXXXXX listenerDownloadLyricWithSongId:resultBlock:]

能够看到中间的部分显现出来函数所对应的汇编代码

iPa逆向之路

然后按快捷键Option+enter即可转为伪OC代码,尽管包含一些的寄存器信息,可是也足以剖析了。一起双击能够跳转到对应的函数内部。

最终

以上便是现在的逆向调研进程,这儿先记录下,后边还会深入研究,有新的发现会同步更新此文章。