第1章:iOS静态分析——从class-dump到Runtime实战

做iOS逆向这么多年,我始终觉得静态分析是基本功。就像学武术要先扎马步,静态分析就是那个马步。你想想看,一个App摆在你面前,你连它里面有什么类、调了什么方法都不知道,怎么下手?

这一章,我会带你走完iOS静态分析的完整链路。从导出头文件,到反汇编分析,再到Mach-O结构解析,最后用Method Swizzling和isa指针的知识,实战分析一个App的私有API调用。

1.1 class-dump:给App“拍X光片”

class-dump这个工具,说白了就是把Mach-O文件里的Objective-C类信息提取出来,生成头文件。我刚开始做逆向时,拿到一个App第一件事就是跑class-dump。为什么?因为OC是动态语言,类的信息都留在二进制里,class-dump就是把这些信息“翻译”成我们能读懂的.h文件。

核心命令:

class-dump -H AppName -o ./Headers

这条命令会把AppName这个Mach-O文件里的所有OC类导出到Headers目录下。

我个人习惯在导出后,先看AppDelegate和ViewController相关的头文件。这些通常是入口,能快速了解App的整体架构。

避坑指南:我曾经遇到一个App,class-dump导出的头文件全是乱码。后来发现是App做了加密,需要先用Clutch或dumpdecrypted砸壳。记住,class-dump只能处理未加密的Mach-O文件。

1.2 Hopper Disassembler:反汇编的“手术刀”

class-dump只能看到OC层面的信息。如果App用了C++、Swift,或者你想看某个方法的汇编实现,就得用Hopper了。

Hopper Disassembler是我最常用的反汇编工具。它能把Mach-O文件反编译成伪代码,虽然不如IDA Pro强大,但对iOS逆向来说完全够用。

用Hopper分析时,我一般会做这几步:

  • 搜索字符串:按Shift+Command+F,搜索URL、API路径、密钥等敏感字符串
  • 查看导入表:看App调用了哪些系统库,特别是私有框架
  • 定位关键函数:比如viewDidLoad、application:didFinishLaunchingWithOptions:

小技巧:在Hopper里,按Option+Enter可以快速跳转到选中函数的实现。我经常用这个功能在class-dump导出的头文件和Hopper的反汇编代码之间来回切换。

1.3 Mach-O文件结构:读懂App的“骨架”

Mach-O是iOS的可执行文件格式。不理解Mach-O结构,你很难真正理解iOS逆向。

Mach-O文件主要分为三部分:

组成部分 说明 逆向关注点
Header 文件头,包含CPU类型、文件类型等信息 判断是arm64还是armv7
Load Commands 加载命令,告诉dyld如何加载这个文件 查看依赖库、入口点、加密信息
Data 实际代码和数据 __TEXT段(代码)、__DATA段(数据)

嗯,这里要注意。Mach-O里有个叫LC_ENCRYPTION_INFO的加载命令,它标记了App是否加密。如果加密了,你直接拿class-dump或Hopper去分析,什么都看不到。必须先砸壳。

重要:otool -l AppName | grep -A 4 LC_ENCRYPTION_INFO可以查看加密状态。如果cryptid为1,说明已加密;为0则未加密。

1.4 Objective-C Runtime:逆向的“内功心法”

OC Runtime是iOS逆向的核心。不理解Runtime,你只能做表面分析。

1.4.1 Method Swizzling:偷天换日

Method Swizzling说白了就是交换两个方法的实现。在逆向中,我们经常用它来Hook系统方法,监控App的行为。

// 交换viewDidLoad和swizzled_viewDidLoad的实现
Method originalMethod = class_getInstanceMethod([UIViewController class], @selector(viewDidLoad));
Method swizzledMethod = class_getInstanceMethod([UIViewController class], @selector(swizzled_viewDidLoad));
method_exchangeImplementations(originalMethod, swizzledMethod);

我曾经用这个技术分析过一个金融App。它把用户输入的密码用了一个私有API加密,我通过Swizzling了UITextFieldtext方法,成功截获了加密前的明文密码。

1.4.2 isa指针:对象的“身份证”

每个OC对象都有一个isa指针,指向它的类对象。通过isa指针,我们可以知道一个对象到底是什么类型。

在arm64架构下,isa指针做了优化,不再直接指向类对象,而是通过位运算得到。但原理不变:isa是连接对象和类的桥梁。

实战技巧:在LLDB调试时,用po [object class]可以查看对象的实际类型。如果发现一个对象的类型和预期不符,那很可能被做了Method Swizzling。

1.5 实战:分析一个App的私有API调用

理论说完了,我们来点实际的。假设我们要分析一个App是否调用了私有API。

步骤是这样的:

  1. 砸壳:用Clutch或dumpdecrypted获取未加密的Mach-O文件
  2. 导出头文件:用class-dump -H导出所有OC头文件
  3. 搜索私有API:在导出的头文件中搜索_开头的类名或方法名(苹果私有API通常以下划线开头)
  4. 反汇编验证:用Hopper打开Mach-O,搜索找到的私有API名称,查看调用上下文
  5. 确认调用:在Hopper中查看调用私有API的汇编代码,确认参数和返回值

举个例子:我曾经分析一个相机App,在class-dump导出的头文件中发现了AVCaptureDevice的私有方法_setTorchMode:。用Hopper一查,果然在某个按钮的点击事件里调用了这个方法。这就是典型的私有API调用。

为什么会有人用私有API?说白了,有些功能苹果没公开,但开发者又想用。比如获取设备的UDID、访问相册的原始数据等。但苹果审核时会扫描私有API调用,一旦发现就会被拒。

注意:分析私有API调用时,要区分是App自己调用的,还是第三方SDK调用的。很多情况下,是第三方SDK偷偷用了私有API,App开发者自己都不知道。

知识体系总览

下面这张图,是我为你整理的本章知识体系。你可以把它当作一张地图,随时回来对照。

iOS静态分析知识体系 iOS静态分析 class-dump 导出头文件 Hopper 反汇编分析 Mach-O 结构解析 OC Runtime 分析 查看OC类结构 识别私有API 搜索字符串 查看导入表 定位关键函数 Header解析 Load Commands __TEXT/__DATA段 Method Swizzling isa指针分析

这张图把本章的知识点串起来了。从class-dump到Hopper,从Mach-O到Runtime,每一步都是环环相扣的。你不需要一次全记住,但每次分析App时,都可以回来看看这张图,找到你现在处于哪个环节。

好了,这一章的内容就到这里。记住,静态分析是逆向的基础,但光看不动手是学不会的。找个App练练手,把class-dump和Hopper用熟,你会发现iOS逆向其实没那么神秘。

公众号:蓝海资料掘金营,微信deep3321