一、MonkeyDev

1、简介

MonkeyDev 是一个工具集合,基于 iOSOpenDev 进行升级并集成到 Xcode 里面,可以用来开发越狱机器的插件,可以很方便地注入动态库并重签名安装到非越狱机器,堪称神器。

2、安装

参考官方文档进行安装:https://github.com/AloneMonkey/MonkeyDev/wiki

3、开始使用

  1. 新建 MonkeyApp 项目。

0042e463aedfee90fd1ac2dc4fa6ac8e

  1. 拖入 已砸壳 的 ipa 包到指定文件夹

cbdfe51ba5f5faeee12318e6ac9ad6de

  1. 配置开发证书。

c4fe4957ddcbaea66aa0747783c62fcb

如无意外即可运行到手机上。

4、其它运行问题

1. 链接错误

6d63a3425c582d18ec96bb089cf07787

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

这是由于 Xcode 10 开始就不再集成 libstdc++ 库,需要把相关的库文件重新添加到对应的路径。

使用 GitHub 上的这个库 https://github.com/devdawei/libstdc- 可以比较方便地添加 libstdc++ 库。

2. Bundle ID

TikTok 对 Bundle ID 应该有校验,用其它 Bundle ID 会导致无法联网,这时候可以在 Build Settings 里面,找到 MONKEYDEV_DEFAULT_BUNDLEID 设为 YES,这时候重新编辑安装到手机即可。

3. 需要国外手机卡

TikTok 对地区有限制,手机需要插上国外手机卡才能进行开播,这样对调试不太友好。

CTCarrier 是iOS上获取运营商信息的系统框架,我们可以对其进行 Hook,使其返回指定运营商信息。

得益于 MonkeyDev 维护了非越狱插件 CocoaPods 私有仓库(https://github.com/AloneMonkey/MonkeyDevSpecs),我们可以直接使用别人提供的插件,使用方法跟我们平时使用 CocoaPods 完全一致,添加对应的源地址即可:

source 'https://github.com/AloneMonkey/MonkeyDevSpecs.git'
source 'https://github.com/CocoaPods/Specs.git'

use_frameworks! 

target 'TikTokDevDylib' do
     pod 'FLEX'
     pod 'MonkeyDevPod', '2.0.0'
     pod 'AYTikTokPod'
     pod 'LookinServer'
end

5、Hook 相关函数

1. Objective-C

Objective-C 是一门动态语言,可以利用运行时的特性,使用 Method Swizzling 技术进行 Hook。

在 MonkeyDev 上使用如下:

CHDeclareClass(AVCaptureSession)

CHMethod1(void, AVCaptureSession, setSessionPreset, NSString *, arg1) {
    NSLog(@"---- - sessionPreset:%@", arg1);
    CHSuper1(AVCaptureSession, setSessionPreset, arg1);
}

CHConstructor {
    CHLoadLateClass(AVCaptureSession);
    CHHook1(AVCaptureSession, setSessionPreset);
}

2. C 语言

C 语言是静态语言,编译后变量、函数都已确定,我们使用 fishhook 框架即可对系统函数进行 Hook,fishhook 原理

使用如下:

static OSStatus (*oldVTDecompressionSessionCreate)(CM_NULLABLE CFAllocatorRef allocator, CM_NONNULL CMVideoFormatDescriptionRef videoFormatDescription, CM_NULLABLE CFDictionaryRef videoDecoderSpecification, CM_NULLABLE CFDictionaryRef destinationImageBufferAttributes, const VTDecompressionOutputCallbackRecord * CM_NULLABLE outputCallback, CM_RETURNS_RETAINED_PARAMETER CM_NULLABLE VTDecompressionSessionRef * CM_NONNULL decompressionSessionOut);

OSStatus myVTDecompressionSessionCreate(CM_NULLABLE CFAllocatorRef allocator, CM_NONNULL CMVideoFormatDescriptionRef videoFormatDescription, CM_NULLABLE CFDictionaryRef videoDecoderSpecification, CM_NULLABLE CFDictionaryRef destinationImageBufferAttributes, const VTDecompressionOutputCallbackRecord * CM_NULLABLE outputCallback, CM_RETURNS_RETAINED_PARAMETER CM_NULLABLE VTDecompressionSessionRef * CM_NONNULL decompressionSessionOut) {
    NSLog(@"---- - myVTDecompressionSessionCreate");
    return oldVTDecompressionSessionCreate(allocator, videoFormatDescription, videoDecoderSpecification, destinationImageBufferAttributes, outputCallback, decompressionSessionOut);
}

CHConstructor {
    struct rebinding rebind;
    rebind.name = "VTDecompressionSessionCreate";
    rebind.replacement = myVTDecompressionSessionCreate;
    rebind.replaced = (void *)&oldVTDecompressionSessionCreate;
    
    struct rebinding rebs[] = {rebind};
    rebind_symbols(rebs, 3);
}

6、Instruments

ca5d606df7ebcba1f8da9ec54b83b3cd

可以使用 Instruments,但目前还无法查看符号。

二、frida

如果手机已经越狱,还可以使用 frida 工具进行调试。

0b67784ebff3dde604b284656e549586

1. 跟踪函数调用

➜  ~ frida-trace -U TikTok -i "VTCompressionSessionCreate"
Instrumenting...
VTCompressionSessionCreate: Loaded handler at "/Users/oudushu/__handlers__/VideoToolbox/VTCompressionSessionCreate.js"
Started tracing 1 function. Press Ctrl+C to stop.
           /* TID 0x25203 */
 45773 ms  VTCompressionSessionCreate()

2. 获取设备进程信息

➜  ~ frida-ps --usb
 PID  Name
----  ------------------------------------------------------------
1139      ACCHWComponentAuthService
1168      AccountExtension
1169      AppManagementExtension
 495      AppSSODaemon
  81      AppleCredentialManagerDaemon
1586      AssetCacheLocatorService
 112      BlueTool
4139      CAReportingService

3. 获取已连接的设备

➜  ~ frida-ls-devices
Id                                        Type    Name
----------------------------------------  ------  ------------
local                                     local   Local System
58e668d38f015b99730912550655d9671f3185fb  usb     iPhone
socket                                    remote  Local Socket

4. 结束进程

➜  ~ frida-kill -D 58e668d38f015b99730912550655d9671f3185fb 5136

5. 调试

➜  ~ frida -U Safari浏览器
     ____
    / _  |   Frida 15.0.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/

[iPhone::Safari浏览器]-> help
Help: #TODO :)

三、其它

目前还处于使用工具的阶段,需要往深挖的话需要了解相关技术的原理,这里先挖一些坑:

  1. class-dump 原理
  2. restore-symbol 原理
  3. fishhook 原理
  4. 动态库注入原理
  5. 重签名原理