前言

上一篇介绍了用Clutch砸壳方法,这一篇介绍的是第二种方式-dumpdecrypted,dumpdecrypted与Clutch不同,他是需要app运行起来(iOS系统会先解密程序再启动),然后从内存中将解密结果dump写入文件中,得到一个新的可执行程序。

准备

  1. 越狱的iPhone

    • Cydia安装OpenSSH(Mac 上远程输入命令操作 iOS 设备)
    • Cydia安装Cycript
    • Cydia安装Apple File Conduit “2”(方便ifunbox等工具访问iOS系统目录)

      安装 afc2add 也是一样,不过我在安装 afc2add 后无法访问系统目录,才用 Apple File Conduit “2” 这个插件的,这个插件要通过添加 apt.25pp.com 这个源来装,你用Cydia的源访问不了,应该是要翻墙。
      (这里小记录下,每次重新越狱, Apple File Conduit “2” 这个插件都要重新安装一遍,不然会失效)

  2. 电脑安装ifunbox,usbmuxd,class-dump

    • iFunBox自己找
    • usbmuxd可通过下面命令安装,前提是你Mac装了Homebrew

      1
      brew install usbmuxd
    • 如果你安装了或者打算装 Monkey Dev 的,就可以不用装 class-dump,因为它里面已经自带了。自己安装 class-dump 可以通过此地址下载,下载后打开,把里面的 class-dump 复制到 /usr/local/bin 路径下,打开终端,执行:

      1
      class-dump

      成功安装好class-dump~

过程

安装dumpdecrypted

  1. 先从GitHub下载dumpdecrypted

    下载地址:https://github.com/stefanesser/dumpdecrypted

  2. dumpdecrypted生成dylib动态库

    解压刚下载的dumpdecrypted-master.zip,终端cd到解压完的路径下,执行make,得到这两个文件

  3. ssh连接iPhone

    • 由于Mac上只支持4位的端口号,所以需要把iPhone的默认端口22映射到Mac上,相当于建立一个Mac和iPhone之间的通道。打开终端,执行:

      1
      iproxy 12345 22
    • 这时终端会显示 waiting for connection 这表示我们已经搭建好Mac和iPhone的通道,现在我们直接和本地的12345端口通信就能和iPhone通信了。保持上一个命令显示的状态,新建个终端执行:

      1
      ssh -p 12345 root@127.0.0.1

      如果要你输入密码则输入:alpine,显示 iPhone:~ root# 代表成功,你可以在后面输入命令操作设备啦。

砸壳

  1. 因为dumpdecrypted是通过利用苹果解密运行起App,再从内存中把解密的文件导出来,所以我们要先把要砸壳的App运行起来,为了方便查找,最好只保留这个App运行中,其他的杀掉,我们执行此命令查看当前手机所有进程:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    iPhone:~ root# ps -e
    PID TTY TIME CMD
    1 ?? 1:55.62 /sbin/launchd
    19 ?? 0:02.34 /usr/sbin/syslogd
    20 ?? 6:18.52 /usr/libexec/UserEventAgent (System)
    21 ?? 0:00.25 /System/Library/PrivateFrameworks/FileProvider.framework/Support/fileproviderd
    22 ?? 0:03.61 /System/Library/PrivateFrameworks/AssistantServices.framework/assistantd
    24 ?? 0:25.35 /usr/libexec/fseventsd
    ...
    2088 ?? 0:03.26 /Applications/MobileMail.app/MobileMail
    2093 ?? 0:00.24 /System/Library/PrivateFrameworks/CoreRecents.framework/recentsd
    2109 ?? 0:07.59 /Applications/AppStore.app/AppStore
    2114 ?? 0:00.18 /System/Library/PrivateFrameworks/FamilyCircle.framework/familycircled
    2117 ?? 0:02.71 /var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/WeChat
    2053 ttys000 0:00.04 -sh
    2118 ttys000 0:00.01 ps -e

    我这次要砸壳的是微信,仔细看了下,找到了个weichat的(一般在后面部分),看到 /var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/WeChat 没,这个路径是App可执行文件的路径,我们等下要砸的就是它。记住这个路径和他前面的序号2117,序号是为了获取App的沙盒路径,为什么要拿到这个路径,因为我们要把 dumpdecrypted.dylib文件 放到此路径下,只有这个路径下,App才有读写权限,才能执行砸壳操作。

    下面是获取App的沙盒路径,所以在cy下我们执行:

    1
    2
    3
    iPhone:~ root# cycript -p 1112
    cy# [NSHomeDirectory() stringByAppendingString:@"/Documents"]
    @"/var/mobile/Containers/Data/Application/E3FD1B0F-E837-465A-A8F3-17EBD3B575DF/Documents"

    成功拿到App沙盒路径,直接通过iFunBox拖动编译得到的 dumpdecrypted.dylib文件 到的 Device/var/mobile/Containers/Data/Application/E3FD1B0F-E837-465A-A8F3-17EBD3B575DF/Documents 目录下。没有的iFunBox的话用此命令也行:

    1
    scp -P 12345 <Mac上dumpdecrypted.dylib的路径> root@localhost:/var/mobile/Containers/Data/Application/E3FD1B0F-E837-465A-A8F3-17EBD3B575DF/Documents/

    我们到沙盒路径下检查看是否拷贝成功(使用 control+d 或者 输入 exit(0) 命令 退出cycript):

    1
    2
    3
    4
    iPhone:~ root# cd /var/mobile/Containers/Data/Application/3B95C567-569F-4B83-951F-14208A203C28/Documents/
    iPhone:/var/mobile/Containers/Data/Application/3B95C567-569F-4B83-951F-14208A203C28/Documents root# ls
    00000000000000000000000000000000 LocalInfo.lst MMappedKV OpenImResource dumpdecrypted.dylib
    CrashReport MMResourceMgr MemoryStat SafeMode.dat heavy_user_id_mapping.dat

    确认存在,那可以进行砸壳了。

  2. 砸壳

    直接执行命令砸壳:

    1
    DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/WeChat

    哎呀呀报错啦:

    1
    2
    3
    4
    5
    6
    iPhone:/var/mobile/Containers/Data/Application/3B95C567-569F-4B83-951F-14208A203C28/Documents root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/WeChat
    dyld: could not load inserted library 'dumpdecrypted.dylib' because no suitable image found. Did find:
    dumpdecrypted.dylib: required code signature missing for 'dumpdecrypted.dylib'
    /private/var/mobile/Containers/Data/Application/3B95C567-569F-4B83-951F-14208A203C28/Documents/dumpdecrypted.dylib: required code signature missing for '/private/var/mobile/Containers/Data/Application/3B95C567-569F-4B83-951F-14208A203C28/Documents/dumpdecrypted.dylib'

    很明显,说我们没签名呢,给 dumpdecrypted.dylib 签个名再重复刚才拷贝到App沙盒路径的步骤,以下是签名方法:

    1
    2
    3
    4
    ## 列出可签名证书
    security find-identity -v -p codesigning
    ## 从上面的证书选一个为dumpecrypted.dylib签名
    codesign --force --verify --verbose --sign "iPhone Developer: xxx xxxx (xxxxxxxxxx)" dumpdecrypted.dylib

    签名成功:

    把这个签名后的 dumpdecrypted.dylib 替换刚才App沙盒路径下的 dumpdecrypted.dylib,重新执行:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    iPhone:/var/mobile/Containers/Data/Application/3B95C567-569F-4B83-951F-14208A203C28/Documents root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/WeChat
    objc[2172]: Class MarsReachability is implemented in both /private/var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/Frameworks/mars.framework/mars (0x10c9454c0) and /private/var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/Frameworks/ConfSDK.framework/ConfSDK (0x10c1adc00). One of the two will be used. Which one is undefined.
    objc[2172]: Class MarsReachability is implemented in both /private/var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/Frameworks/mars.framework/mars (0x10c9454c0) and /private/var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/Frameworks/matrixreport.framework/matrixreport (0x105175590). One of the two will be used. Which one is undefined.
    objc[2172]: Class AVPlayerView is implemented in both /System/Library/Frameworks/AVKit.framework/AVKit (0x1b4954298) and /var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/WeChat (0x104b856f0). One of the two will be used. Which one is undefined.
    mach-o decryption dumper
    DISCLAIMER: This tool is only meant for security research purposes, not for application crackers.
    [+] detected 64bit ARM binary in memory.
    [+] offset to cryptid found: @0x100004ca8(from 0x100004000) = ca8
    [+] Found encrypted data at address 00004000 of length 65617920 bytes - type 1.
    [+] Opening /private/var/containers/Bundle/Application/9A36EC10-CE81-4D44-8F5E-2B4F70F3B3D4/WeChat.app/WeChat for reading.
    [+] Reading header
    [+] Detecting header type
    [+] Executable is a plain MACH-O image
    [+] Opening WeChat.decrypted for writing.
    [+] Copying the not encrypted start of the file
    [+] Dumping the decrypted data into the file
    [+] Copying the not encrypted remainder of the file
    [+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset ca8
    [+] Closing original file
    [+] Closing dump file

    至此,砸壳成功,毫无意外,我们会在沙盒路径下发现多了个新文件:

    这就是我们要的脱壳文件啦

导出头文件

  1. 拿到可执行文件

    从上面砸壳我们已经成功得到砸完壳,现在只要把 WeChat.decrypted 这个文件从手机复制出来放到你喜欢的路径下(用iFunBox或者scp命令),我们要利用这个文件来导出头文件。

  2. 导出头文件

    用class-dump导出头文件,到终端执行:

    1
    class-dump -H <你放WeChat.decrypted文件的路径> -o <你打算放导出的头文件的文件夹路径>

    喝杯咖啡,emmmm,头文件就出来啦。

总结

至此,dumpdecrypted砸壳&获取头文件完毕,和Clutch最后一样,你可以用ida来打开上面得到WeChat.decrypted,弄完是不是觉得dumpdecrypted有点麻烦呢?没关系,第三种砸壳方法-Frida,是最方便省事的方式,站在巨人的肩膀简直不要太爽哈哈~请接下看下一篇