在前面的例子中,利用Cycript可以对某个App进行调试,但是其效果只是临时的,因为一旦杀掉App进程,就会重新恢复成原样。那么如何在修改完APP后,能永久性的保持效果呢?

接下来就需要利用到Theos,Theos是一系列工具的合集,可以通过Theos创建tweak项目,Hook目标App的一些方法,然后对tweak项目进行编译、打包,生成deb插件(其实就是一个动态库文件),安装到iPhone上,其原理接下来会说到

安装签名工具ldid

ldid是一个命令行签名工具,可以用于导出的签名文件、对文件进行重签名等操作

  • 首先安装homebrew(类似于iOS中的CocoaPods)
$ /usr/bin/ruby -e "$(curl -fsSL
https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • 利用brew安装ldid
brew install ldid

修改环境变量

  • 编辑用户的配置文件
vim ~/.bash_profile
  • .bash_profie 文件后面加入两行
# THEOS 代表着路径 ~/theos
export THEOS=~/theos
# 让~/theos/bin目录的配置文件在全局都可以生效, $PATH 代表其他的一些全局配置文件
export PATH=$THEOS/bin:$PATH
  • .bash_profie 配置的环境变量立即生效
source ~/.bash_profile

配置好环境变量,可以打印查看

python ddddocr怎么打包让其它电脑运行_ios

下载Theos

  • 建议将代码下载到$THEOS目录(也就是~/theos目录)
git clone --recursive https://github.com/theos/theos.git $THEOS

创建tweak项目

  • cd到一个存放tweak项目代码的地方(例如桌面),创建项目
cd ~/Desktop
# 开始创建项目
nic.pl
  • 选择 iphone/tweak项目

编写Tweak项目

执行完前面步骤后,会在桌面生成一个tweaktest文件夹,里面有四个文件

python ddddocr怎么打包让其它电脑运行_xcode_02

编写Makefile文件

在前面加入环境变量,也就是通过什么IP和端口连接手机(因为iPhone和Mac通过USB绑定,直接输入Mac的本地IP和绑定端口即可)

export THEOS_DEVICE_IP=127.0.0.1
export THEOS_DEVICE_PORT=2222

include $(THEOS)/makefiles/common.mk
TWEAK_NAME = ting_tweak
ting_tweak_FILES = Tweak.xm
include $(THEOS_MAKE_PATH)/tweak.mk
after-install::
    install.exec "killall -9 SpringBoard"

如果不希望每个项目的Makefile文件都需要去编写以上环境变量,可以直接添加到用户配置文件(.bash_profile)中即可,$ source ~/.bash_profile 让配置文件生效

$ vim ~/.bash_profile
export THEOS=~/theos
export PATH=$THEOS/bin:$PATH
export THEOS_DEVICE_IP=127.0.0.1
export THEOS_DEVICE_PORT=2222

$ source ~/.bash_profile

编写代码

打开Tweak.xm文件,输入需要修改的代码,例如hook某个方法:

#import <UIKit/UIKit.h>
%hook ViewController
// 对ViewController的声明,可识别self关键字
@interface ViewController
// 编译时可识别[self view]代码
- (id)view;
@end

- (void)touchesBegan:(id)touches withEvent:(id)event
{
	UIView *v = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
 	v.backgroundColor = [UIColor greenColor];
   	[[self view] addSubview:v];
}

%end

编译、打包、安装

执行以下命令之前,先保证让Mac和iPhone进行端口绑定

  • 编译,执行 $ make
  • 打包,执行 $ make package
  • 安装, 执行 $ make install

make package时可能会出现如下错误:

错误1
package name has characters that aren't lowercase alphanums or '-+.'
  • 是因为项目名,bundleID有大写的,需要改成小写的
错误2
open2: exec of lzma -c1 failed at /Users/wushiguang/theos/bin/dm.pl line 116
  • 打包压缩方式问题,将deb.mk 文件第6行改成 _THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= gzip
vim $THEOS/makefiles/package/deb.mk
_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= gzip
错误3
Error: You do not have an SDK in
/Library/Developer/CommandLineTools/Platforms/iPhoneOS.platform/Developer/S
DKs
  • 多个Xcode问题,需要指定Xcode路径
sudo xcode-select --switch
/Applications/Xcode.app/Contents/Developer/
错误4
make
> Making all for tweak xxx...
make[2]: Nothing to be done for `internal-library-compile'.
  • 之前编译过,有缓存导致的,clean一下即可
make clean

Logos常用语法

Logos的语法可以在这里看到,下面只介绍一些常用的语法

  • %hook、%end ,hook一个类的开始和结束
  • %log,打印方法调用详情,可以通过Xcode -> Window -> Devices and Simulators 查看日志
  • HBDebugLog,跟NSLog类似
  • %new,添加一个新的方法(区别于hook的方法)
  • %c(className) ,生成一个Class对象,例如%c(NSObject),类似于NSStringFromClass()、objc_getClass
  • %orig,调用函数原来的代码逻辑
  • %ctor,在加载动态库(也就是所编写的代码)的时候调用
  • %dtor,在App退出时调用
  • logify.pl,可以将某个需要Hook类的头文件所有方法打上log,并保存生成一个xm文件,方便函数调用追踪
# test为目标头文件,xx为生成的xm文件
logify.pl test.h > xx.xm

logify.pl生成的xm文件 ,很多时候编译不能通过,需要一些处理
1、删掉_weak
2、删掉inout
3、删掉协议,或者声明一下协议信息@protocol xxxDelegate
4、删掉- (void).cxx_destruct { %log; %orig; }
5、删掉HBLogDebug(@" = 0x%x", (unsigned int)r);
6、替换类名为Void,比如将 XXPerson * 替换为 void *,或者声明一下类信息@class XXPerson

Tweak项目的图片管理和多文件开发

图片资源的管理

如果有额外的资源文件,例如图片等,就新建一个layout文件夹(该文件夹对应着手机的根目录),然后依次创建以下目录 /Library/PreferenceLoader/preferences/ 或/Library/Caches 文件夹,Wechat就是所需要逆向的项目文件夹,Wechat下面就是放着资源文件,在编写代码时引用这些资源文件,需要带上全路径

  • 路径1

python ddddocr怎么打包让其它电脑运行_App_03

  • 路径2

    仔细观察会发现路径1的preferences目录下,有着reveal的图片资源,说明该路径下的资源文件是偏整个系统的,所以更推荐放在路径2目录下
多文件开发

在tweak项目开发中,有可能会有多个文件,例如增加 Dog.hDog.m,下面分几种情况介绍

情况1

python ddddocr怎么打包让其它电脑运行_xcode_04


这个时候如果直接执行make指令,就会报Dog类找不到的错误信息,所以需要指定Dog的路径,打开Makefile文件,tweaktest_FILES就表示需要参与编译的文件,在Tweak.x后加上空格,然后写上Dog.m,就表示Tweak.x和Dog.m参与编译

tweaktest_FILES = Tweak.x Dog.m
情况2

创建一个src文件夹管理

python ddddocr怎么打包让其它电脑运行_xcode_05


这种情况前面加上对应文件夹即可,但是后面的Dog.m改成了通配符*.m,意思src目录下的.m文件都参与编译

tweaktest_FILES = src/Tweak.x src/*.m
情况3

python ddddocr怎么打包让其它电脑运行_App_06

移除插件

如果不再逆向某App,在iPhone目录~/Library/MobileSubstrate/DynamicLibraries/下找到我们的deb插件生成的.dylib和.plist文件,删除这两个文件,然后重启SpringBoard即可删除插件

python ddddocr怎么打包让其它电脑运行_App_07


还有一种办法就是在Cydia中找到该插件,然后卸载,这种方式更干净一点,推荐使用

python ddddocr怎么打包让其它电脑运行_xcode_08

Tweak的实现原理过程

  • $ make,编译Tweak代码为动态库(*.dylib)
  • $ make package,将dylib打包为deb文件
  • $ make install,将deb文件传送到手机上,通过Cydia安装deb
  • 插件将会安装在 /Library/MobileSubstrate/DynamicLibraries 文件夹中
  • *.dylib:编译后的Tweak代码
  • *.plist:存放着需要hook的AppID
  • 当打开App时,Cydia Substrate(Cydia已自动安装的插件)会让App去加载对应的dylib,修改App内存中的代码逻辑,去执行dylib中的函数代码
  • theos的tweak并不会对App原来的可执行文件进行修改,只是修改了内存中的代码逻辑

Tweak的一些疑问点

  • 未脱壳的App也是支持tweak的,因为tweak是在内存中实现,没有修改App的可执行文件
  • tweak的效果是否永久性取决于App代码是否被修改过
  • 未越狱的手机不支持tweak
  • 可以对Swift/C函数进行tweak,但是方式跟OC不一样
  • 也可以对游戏进行tweak,但是由于游戏大多是通过C++/C#编写,而且类名、函数名会进行混淆