一、工程准备
1.1 安装签名工具
1 | $ brew install ldid |
1.2 修改环境变量
编辑用户的配置文件
1
$ vim ~/.bash_profile
在
.bash_profile
文件后加入变量,配置变量可参考macOS环境变量配置1
2
3# THEOS
export THEOS=~/theos
export PATH=$PATH:$THEOS/bin让
.bash_profile
配置的环境变量立即生效,或者重启终端1
$ source ~/.bash_profile
##1.3 下载Theos
建议在上述配置的$THEOS
目录下载代码:
1 | $ git clone --recursive https://github.com/theos/theos.git $THEOS |
二、项目开发-喜马拉雅去广告
开发一个tweak项目的流程大致如下:
- 确认开发需求:比如去广告、加会员,破解加锁功能等等。
- 根据需求,确认需要修改的方案。
- 比如去广告需要确定视图关系,对视图关系进行分析。
- 加会员、破解功能则需要分析函数调用、逻辑关系,猜测实现,最后尝试hook逻辑。
- 项目开发
- Clutch、dumpdecrypted破壳;
- class dump导出头文件;
- Reveal、Cycript分析界面;
- 分析类关系、函数调用逻辑,尝试进行hook;
- 调试、编译、打包、安装;
- 重签名、发布;
我们在这里,将会实施前5步,重签名会在后面讲述。
2.1 新建Tweak项目
我们今天破解的是喜马拉雅FM APP。
需求是:去广告。
cd到存放项目代码的目录,此处:
1 | $ cd ~/Desktop/crackApp/ting/ |
Project Name:
- 必选项
- 此处我们工程的名字是tingtweak;
Package Name
- 包名,一般规则即可,也可以随便
- 此处,我们com.luci.tingtweak
Author/Maintainer Name
- 作者,当然是Wenghengcong
- 直接敲回车默认Mac用户名
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]
- 我们要tweak App的bundle id,针对喜马拉雅tweak:com.gemd.iting
- 可以使用Cycript或者MJAppTool来查看对应的App的Bundle Identifier;
[iphone/tweak] List of applications to terminate upon installation (space-separated, ‘-‘ for none) [SpringBoard]
- 直接回车
2.2 项目文件结构
2.2.1 MakeFile
MakeFile,指定工程用到的文件、框架、库等信息,将整个过程自动化。
我们看MakeFile文件:
1 | include $(THEOS)/makefiles/common.mk |
在前面加入环境变量,写清楚通过哪个IP和端口访问手机:
1 | export THEOS_DEVICE_IP=127.0.0.1 |
此处通过本机地址,及10010端口访问手机,参考逆向(一)环境搭建通过USB连接手机一节。
如果不希望为每个项目的MakeFile都export端口,可以添加到用户配置文件中,同上面添加$THEOS
变量类似,source生效:
1 | # THEOS |
- Tweak默认编码方式是MRC 如果需要ARC的话 在MakeFile中插入
1 | //其他项目,请修改tingtweak为项目名 |
2.2.2 control
主要是项目有关的信息,比如项目的名称、版本、开发者等信息。
1 | Package: com.luci.tingtweak |
2.2.3 tingtweak.plist
主要是设置需要被逆向的app的bundle Id,如果需要逆向多个APP,就在Bundles数组中添加其bundle Id:
1 | { Filter = { Bundles = ( "com.gemd.iting" ); }; } |
2.2.4 xm文件
xm就是hook代码文件。
2.3 脱壳、导出头文件
Clutch -d 破壳,始终无法破壳,则换采用dumpdecrypted工具
先使用MJAppTool列出应用列表,获取喜马拉雅的app路径,得到:
/private/var/mobile/Containers/Bundle/Application/77CC1D65-FAD8-4E87-AA39-88756270F899/ting.app/
dumpdecrypted破壳:
破壳,执行命令:
5s:~ root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /private/var/mobile/Containers/Bundle/Application/77CC1D65-FAD8-4E87-AA39-88756270F899/ting.app/ting
在
/var/root
找到对应的破壳文件,拷贝到电脑
class dump导出头文件,执行命令:
class-dump -H ting -o Headers
2.4 分析界面
收听界面,展示了如下广告:

通过Reveal分析,基本可以判定广告视图类为:XMSoundPatchImageView
可以通过Cycript验证上面的猜想:
1 | //ps -A查找到喜马拉雅进程id 893 |
通过上面移除,我们从手机看到,广告没有了。
猜想是对的。
2.5 编写代码
下面,我们就要开始针对XMSoundPatchImageView来做一点事情了。
先从之前导出的头文件里看看XMSoundPatchImageView类:
1 |
|
从上面的头文件,我们发现的信息不多,但是我们可以直接hook掉视图,将该视图始终置为nil。
在Tweak.xm文件中:
1 | %hook XMSoundPatchImageView |
2.6 编译、打包、安装、卸载
在电脑Tweak项目目录下:
2.6.1 编译
1 | make |
2.6.2 打包
打包成deb:
1 | make package |
默认make package打包debug版本,如果要打包release版本:
1 | make package debug=0 |
版本号,可以再
control
文件中指定;debug包会比release版本大,主要包含了一些调试信息;
make package 包含了make指令的动作。
2.6.3 安装
默认会重启SpringBoard
1 | make install |
流程如下:
安装完之后,会重启Springboard,再次打开喜马拉雅,惊喜的是,广告没了!
2.6.4 卸载
直接去删除对应的动态库及plist文件。
/Library/MobileSubstrate/DynamicLibraries
Cydia直接卸载
2.7 错误
2.7.1 - make package
1 | $ make package |
是因为打包压缩方式有问题,改成gzip压缩就行。
修改dm.pl文件,用#号注释下面两句
1
2
3$ vim $THEOS/vendor/dm.pl/dm.pl
#use IO::Compress::Lzma;
#use IO::Compress::Xz;修改deb.mk文件第6行的压缩方式gzip
1
2$ vim $THEOS/makefiles/package/deb.mk
_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= gzip
2.7.2 - make的错误
1)
1 | $ make |
是因为多个Xcode(安装多个Xcode),需要指定Xcode。
1 | $ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/ |
2)
1 | $ make |
之前编译过有缓存,需要clean。
1 | $ make clean |
三、更近一步-微信加功能
1 | 5s:~ root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /private/var/mobile/Containers/Bundle/Application/4E7CFE17-8B9E-4B55-84B1-14E70653EFC3/WeChat.app/WeChat |
3.1 多个tweak文件
假如新建Cell文件夹存放对应的hook代码:
那么在MakeFile中指定该文件:
1 | tweakwechat_FILES = Tweak.xm Cell/MMTableViewCell.xm |
需要注意的是:
每个文件以空格隔开
假如以通配符配置如下:
1
tweakwechat_FILES = Tweak.xm Cell/*.xm
会报错:
1
2
3
4
5
6
7clang: error: no such file or directory: '/Users/wenghengcong/Desktop/crackApp/wechat/tweakwechat/.theos/obj/debug/armv7/Cell/MMTableViewCell.xm.mm'
clang: error: no input files
make[3]: *** [/Users/wenghengcong/Desktop/crackApp/wechat/tweakwechat/.theos/obj/debug/armv7/Cell/*.xm.298cc4f9.o] Error 1
rm /Users/wenghengcong/Desktop/crackApp/wechat/tweakwechat/.theos/obj/debug/armv7/Tweak.xm.mm /Users/wenghengcong/Desktop/crackApp/wechat/tweakwechat/.theos/obj/debug/armv7/Cell/*.xm.mm
make[2]: *** [/Users/wenghengcong/Desktop/crackApp/wechat/tweakwechat/.theos/obj/debug/armv7/tweakwechat.dylib] Error 2
make[1]: *** [internal-library-all_] Error 2
make: *** [tweakwechat.all.tweak.variables] Error 2
3.2 资源文件
资源文件存放,需要在tweak项目中新进layout
文件夹用于存放。
3.2.1 layout
layout
相当于iOS 系统根目录,在layout路劲中创建的文件路径,在打包之后,都会映射到iOS系统中。
在iOS中的映射:
所以,假如需要存放资源,规划好存放路径。
3.2.2 读取
1 | //路径,在文件头部定义个宏 |
3.3 宏
宏定义语法和之前一致:
1 |
3.4 安装脚本
将以上打包等步骤编写为脚本:
1 | # bftweak-make.sh |
安装成功之后:

五、Theos
目录结构:https://github.com/theos/theos/wiki/Structure
环境变量:http://iphonedevwiki.net/index.php/Theos
5.1 theos-tweak实现过程
编写Tweak代码
make:编写Tweak代码为动态库(*.dylib)
make package:将dylib打包为deb文件
make install:将deb文件传送到手机上,通过Cydia安装deb
插件将会安装在
/Library/MobileSubstrate/DynamicLibraries
文件夹中- *.dylib:编译后的Tweak代码
- *.plist:存放着需要hook的App Id
当打开APP时
- Cydia Substrate(Cydia已自动安装的插件)会让APP去加载对应的dylib
- 修改APP内存中的代码逻辑,去执行dylib中的函数代码
5.2 Logos语法
http://iphonedevwiki.net/index.php/Logos
%hook %end:hook 一个类的开始与结束
%log:打印方法调用详情
- 通过Xcode -> Window -> Devices and Simulators 查看日志
HBDebugLog:和NSLog类似
%new:添加一个新方法
%c(className):生成一个Class对象,比如%c(NSObjct) ,类似NSStringFromClass()、objc_getClass()
%orig:函数原来的代码逻辑
%ctor:在加载动态库时调用
%dtor:在程序退出时调用
logify.pl xm:将一个头文件快速转换成一家包含打印信息的xm文件
1
logify.pl xx.h > xx.xm
5.3 logify.pl
1 | logify.pl xx.h > xx.xm |
logify.pl生成的xm文件,很多时候编译不通过,需要进行一些处理
- 删掉__weak
- 删掉inout
- 删掉协议
- 或者声明一下协议信息@protocol XXDelegate
- 删除- (void).cxx_destruct { %log; %orig; }
- 删除 HBLogDebug(@” = 0x%x”, (unsigned int)r);
- 将所有不认识的类,均替换成id
- 比如instancetype 直接替换id
- 替换类名为void,比如XXPerson *** 替换为 **void *
- 或者声明一下类信息 @class XXPerson
六、其他一些小tip
- SpringBoard的目录:/System/Library/CoreService/SpringBoard.app
- 未脱壳的APP也支持tweak,因为tweak是在内存中以动态库的形式实现的,并没有修改
.app
包中的可执行文件。 - tweak效果是否一直有效,只要tweak用到的代码没有修改过,就一直有效。假如更新到新版本,用到的代码有修改,就会失效;
- 未越狱手机不支持tweak;
- 当前已经逐步对Swift项目进行支持;
- 对游戏项目进行tweak难度大,主要因为游戏大多由C/C++/C#编写的,一般也会进行代码混淆;