这个系列,是很早听 MJ 课程时的整理,现在分享出来。 其中一些参考资料有些有引用,有些可能忘记添加了,如果有引用部分资料,可以联系我。
iOS 逆向(一)环境搭建
iOS 逆向(二)Cycript
iOS 逆向(三)逆向工具
iOS 逆向(四)脱壳
审核中 iOS 逆向(五)Theos工具
iOS 逆向(六)动态调试
iOS 逆向(七)重签名
一、逆向流程
1.1 界面分析
- Cycript:界面分析语言,使用Objective-C 和 Javascript调试App。这部分已经在上一篇逆向(二)Cycript中作过论述。
- Reveal:界面分析工具,非常强大和方便。
1.2 代码分析
对Mach-O文件的静态分析,有以下工具:
- class-dump:脱壳工具,将在下一篇逆向(四)脱壳中讲述。
- MachOView:Mach-O查看工具
- Hopper Disassembler、ida是反汇编工具。能直接进行代码的改写。
1.3 动态调试
对运行中的APP进行代码调试,工具包括:
- debugserver:iPhone内动态调试命令行工具,将在逆向(六)动态调试。
- LLDB:Xcode提供的调试工具。
1.4 代码编写
注入代码到APP中,必要时还可能需要重新签名、打包ipa。
具体实现,参考逆向(五)Theos工具、逆向(六)动态调试。
二、界面分析
Cycript在上篇文章中已经介绍。所以此处着重介绍Reveal。
2.1 软件
Mac版本
官网:revealapp.com 通过邮箱可获得14天试用期.
手机版
Reveal Loader
一定要安装该源的loader。
2.2 调试
2.2.1 设置-Reveal
安装完Reveal Loader后,打开【设置】,找到Reveal
,选择需要调试的APP
2.2.2 加载库
找到Mac的Reveal中的RevealServer
文件,覆盖iPhone的/Library/RHRevealLoader/RevealServer
文件
之后,最好重启桌面,可以在iPhone上输入终端命令
- 重启SpringBoard:killall SpringBoard
- 重启手机:reboot
2.2.3 调试
打开Mac版本Reveal,在手机上开启允许Reveal调试的APP,Reveal mac就会出现调试APP。
如图按照上述步骤没有连上app,问题解决 1)安装 Reveal2Loader 2) 打开Reveal选择顶部菜单Help->Show Reveal Library in Finder->iOS Library,把RevealServer.frameworkr拷贝到手机Device->Library->Frameworks文件夹下,拷贝方式可以通过iFunBox手动操作 3)重新启动手机之后可以看到app显示出来
三、代码分析
3.1 class-dump
顾名思义,它的作用就是把Mach-O文件的class信息给dump出来(把类信息给导出来),生成对应的.h头文件
下载地址见文末,下载完成后,将class-dump文件复制到Mac的/usr/local/bin
目录,这样在终端就能识别class-dump
命令了
常用格式
//直接在控制台输出
$ class-dump ~/Desktop/jike
//-H 表示要生成头文件
//-o 用于制定头文件的存放目录
$ class-dump -H Mach-O文件路径 -o 头文件存放目录
- 注:假如在加壳应用中进行导出,只会导出一个头文件,先要进行脱壳才能导出完整的头文件列表。
3.2 Hopper Disassmbler
Hopper Disassmbler能够将Mach-O文件的机器语言代码反编译成汇编代码、OC伪代码或者Swift伪代码
另外,IDA同样是反汇编工具,作用同Hopper类似。
3.2.1 代码编译过程
不同的OC代码,编译出来的汇编代码可能是一样的
但是在同一种架构平台下,每一条汇编指令都有与之对应的唯一的机器指令
3.2.2 使用
常用快捷键
Shift + Option + X 找出哪里引用了这个方法
3.3 MachOView
MachOView是查看Mach-O文件的工具,Mach-O是苹果平台的可执行文件格式,其具体可以参考Mach-O(一)结构、Mach-O(二)内存分布。
该工具是开源工具,可从Github下载。
MachOExploer和MachOView功能一样,也是开源工具。Github地址
四、共享库缓存提取
在iOS中,系统库,如UIKit、Foundation等,苹果为了提高效率,将这些库都打包成一个动态库,并在系统启动的时候加载,这个集合库,就叫做共享库缓存。
我们在逆向时,为了分析代码,需要将该共享库提取出来。
4.1 dsc_extractor提取
在macOS/iOS中,是使用了/usr/lib/dyld
程序来加载动态库。
dyld,dynamic link editor(动态链接编辑器),也叫dynamic loader(动态加载器)。
所以第一种方式,直接以dyld的方式提取。dyld源码地址参考文末。
下载最新代码,本文更新时,最新版本是dyld-635.2
4.1.1 编译dsc_extractor
可以使用dyld源码中的launch-cache/dsc_extractor.cpp
将#if 0前面的代码删除(包括#if 0),把最后面的#endif也删掉
最后只剩下:
#include <stdio.h>
#include <stddef.h>
#include <dlfcn.h>
typedef int (*extractor_proc)(const char* shared_cache_file_path, const char* extraction_root_path,
void (^progress)(unsigned current, unsigned total));
int main(int argc, const char* argv[])
{
if ( argc != 3 ) {
fprintf(stderr, "usage: dsc_extractor <path-to-cache-file> <path-to-device-dir>\n");
return 1;
}
//void* handle = dlopen("/Volumes/my/src/dyld/build/Debug/dsc_extractor.bundle", RTLD_LAZY);
void* handle = dlopen("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/lib/dsc_extractor.bundle", RTLD_LAZY);
if ( handle == NULL ) {
fprintf(stderr, "dsc_extractor.bundle could not be loaded\n");
return 1;
}
extractor_proc proc = (extractor_proc)dlsym(handle, "dyld_shared_cache_extract_dylibs_progress");
if ( proc == NULL ) {
fprintf(stderr, "dsc_extractor.bundle did not have dyld_shared_cache_extract_dylibs_progress symbol\n");
return 1;
}
int result = (*proc)(argv[1], argv[2], ^(unsigned c, unsigned total) { printf("%d/%d\n", c, total); } );
fprintf(stderr, "dyld_shared_cache_extract_dylibs_progress() => %d\n", result);
return 0;
}
编译dsc_extractor.cpp,获得dsc_extractor
$ clang++ -o dsc_extractor dsc_extractor.cpp
或者
-
- 直接将if 0修改为if 1
-
- 编译代码
$ clang++ -o dsc_extractor ./dsc_extractor.cpp dsc_iterator.cpp
4.1.2 使用dsc_extractor
动态库共享缓存在iPhone的目录为:/System/Library/Caches/com.apple.dyld
,将其拷贝到电脑上:
然后解析出动态库:
// dsc_extractor 缓存 输出文件夹
$ dsc_extractor dyld_shared_cache_armv7s armv7s
4.2 jtool提取
工具地址:JTool
用法
//提取UIKit动态库
$ jtool -extract UIKit path/to/dyld_shared_cache
//提取全部动态库,注意,该提取动作会产生超大的文件,10G+
$ jtool -lv cache_armv7 | cut -c 24- | tail +5 | while read line ; do jtool -extract $line cache_armv7 ; done
4.3 dyld_cache_extract
dyld_cache_extract 是一个GUI工具,蛮方便的工具。
五、动态调试
5.1 MJAppTools
【越狱-逆向】处理iOS APP信息的命令行工具。MJAppTools有详细说明。
5.2 其他命令
其它常用命令,比如lldb、otool、nm、codesign。
参考
链接