常用的逆向手段有
- 通过
Reveal
查看App的视图和ViewController - 通过
cycript
动态调试正在运行的App - 通过
class-dump
导出脱壳后的可执行文件的头文件 - 通过
IDA
或Hopper
反编译脱壳后的可执行文件
通过逆向确定了实现逻辑,可以通过Theos
的tweak编写hook插件
安装Theos
1. 下载
1 | sudo git clone --recursive https://github.com/theos/theos.git ~/theos |
2. 添加环境变量
编辑~/.bash_profile
1 | export THEOS=~/theos |
打开终端,这时候可以使用命令了nic.pl
1 | $ nic.pl |
3. 创建tweak项目
1 | # 选择 [10.] iphone/tweak |
得到4个文件
1 | control |
Tweak.x
就是源码文件,编写tweak代码
1 | %hook ClassName |
编写Tweak
Logos
语法其实是CydiaSubstruct框架提供的一组宏定义。便于开发者使用宏进行HOOK操作。语法简单,功能强大且稳定。
Logos语法分为三大类
- Top level
- Block level
- Function level
Top level
这个TopLevel指令不放在BlockLevel中。%config
全局配置%hookf
:用于hook符号(C/C++方法)%ctor
会在动态库(dylib)被加载的时候调用,用于初始化%dtor
会在程序结束的时候调用,通常用于回收资源
Block level
这一类型的指令会开辟一个代码块,以%end
结束
%group
与%init
配合使用,%group
用于给代码块分组,%init
用于让代码块生效
1 | %group iOS8 |
%hook
用于hook类方法,%new
用于声明新方法
1 | %hook SBApplicationController |
%subclass
用于新增类,新增方法都要加上%new
1 | %subclass MyNewObject : NSObject |
使用新类MyNewObject
1 | MyNewObject *myObject = [[%c(MyNewObject) alloc] init]; |
Function level
这一块的指令就放在方法中。%init
:如上,与%group
配合使用%class
:废弃不用%c(className)
:生成一个Class对象,如:%c(NSObject),相当于NSObject.class%orig
:调用方法原来的实现,包括参数%log
:打印方法和参数
编译
编译配置
再Makefile
配置编译选项和设备信息
1 | # 安装完成后重启SB |
安装到手机
1 | # 编译(make package包含了make,这个也可以省略) |
合并起来
1 | make packages debug=0 && make install |
包会被安装到/Library/MobileSubstrate/DynamicLibraries/
目录下
1 | /Library/MobileSubstrate/DynamicLibraries/xxx.plist(存放要hook App的bundleId) |
资源处理
有时候我们有一些资源需要添加到插件中,例如图片
在tweak中使用到的资源,可以放到工程的layout/Library/PreferenceLoader/Preferences/xxx
下面,在代码中通过绝对路径读取,工程中的layout
路径相当于手机的根路径,该路径下的文件会被安装到手机对应的路径下
1 | - Makefile |
上面icon.png
资源会被安装到手机的/Library/PreferenceLoader/Preferences/mytweak/icon.png
路径下
多文件
插件代码多的时候,可能会有多个源文件(Person.m
, Tweak1.mx
, Tweak2.mx
),如下
1 | - Makefile |
需要在Makefile里面配置需要编译的文件,使用空格隔开
1 | tweakwechat_FILES = src/Tweak1.xm src/Tweak2.xm src/Model/Person.m |
如果文件多,可以使用通配符*
1 | tweakwechat_FILES = src/*.xm src/Model/*.m |
在Tweak1.mx
中引用其他头文件的时候需要使用相对路径
,如下
1 |
Theos-Tweak原理
make
编译代码为动态库dylibmake package
将 dylib 和资源打包成 debmake install
将 deb 发送到手机上,并通过 cydia 安装 deb- 插件会安装到
/Library/MobileSubstrate/DynamicLibraries
- 启动App,
Cydia Substrate
会根据已装插件的plist里面配置的bundleId与App的bundleId一致,就会自动注入对应的dylib - dylib会根据编写的代码自动hook对应的类和方法
卸载插件只需要删除/Library/MobileSubstrate/DynamicLibraries
里面对应的xxx.dylib
和xxx.plist
即可,如果有包含资源的话,还需要把对应的资源删掉
未脱壳的App也可以注入dylib
在内存中修改逻辑,不修改原来的App