前言
I、tweak
tweak,它是各种破解补丁的统称
iOS的tweak大致分为两种:
- 第一种是在cydia上发布的,需要越狱才能安装,大部分是deb格式的安装包.
iOS在越狱后,会默认安装一个名叫mobilesubstrate的动态库,它的作用是提供一个系统级的入侵管道,所有的tweak都可以依赖它来进行开发.
目前主流的开发工具有theos和iOSOpenDev,前者是采用makefile的一个编译框架,后者提供了一套xcode项目模版,可以直接使用xcode开发可调试,但是这个项目已经停止更新了,对高版本的xcode支持不好。(推荐后来的新版本monkeydev
)
- 第二种是直接打包成ipa安装包,并使用自己的开发证书或者企业证书签名,不需越狱也可以安装,可直接放到自己的网站上,可实现在线安装;对于没有越狱的手机,由于权限的限制,我们是没有办法写系统级的tweak的,例如springboard的补丁是没法运行的,这种tweak大多是针对某个app,把目标app进行修改注入处理,再重新签名和发布,有点类似于windows软件的xxx破解版、xxx免注册版
1.1 注入原理
1.1.1 cycript的原理:
其动态库注入的原理,与我们常见的通过LC_LOAD_DYLIB在可执行文件中注入动态库不同.
cycript的操作是 : 抓取到要挂载的应用, 由于越狱机上拥有权限,所以直接在挂载的进程上创建一个挂起的线程, 然后在这个线程里申请一片用于加载动态库的内存,然后恢复线程,动态库就被注入
1.1.2 二次打包动态库的注入
二次打包动态库的注入,是通过修改可执行文件的Load Commands来实现的. 在Load Commands中增加一个LC_LOAD_DYLIB , 写入dylib路径,这样程序执行的时候, 就会编译这个 LC_LOAD_DYLIB 找到要注入的 dylib,加载动态库 .
1.1.2.1 Mobilesubstrate:
著名的method swizzling技术,他就是iOS的注入原理,类似于windows的钩子,所以我们注入也称为hook
Mobilesubstrate为了方便tweak开发,提供了三个重要的模块:
- MobileHooker 就是用来做上面所说的这件事的,它定义一系列的宏和函数,底层调用objc-runtime和fishhook来替换系统或者目标应用的函数
- MobileLoader 用来在目标程序启动时根据规则把指定目录的第三方的动态库加载进去,第三方的动态库也就是我们写的破解程序,他的原理下面会简单讲解一下
- Safe mode 类似于windows的安全模式,比如我们写的一些系统级的hook代码发生crash时,mobilesubstrate会自动进入安全模式,安全模式下,会禁用所有的第三方动态库
1.2 mobileloader注入原理详细说明
Mach-O文件的数据主体可分为三大部分:
- 头部(Header)
- 加载命令(Load commands)、
- 数据(Data)
mobileloader会在目标程序启动时,会根据指定的规则检查指定目录是否存在第三方库,如果有,则会通过修改二进制的loadCommands,来把自己注入进所有的app当中,然后加载第三方库。
下面用machoview来打开一个真实的二进制文件给大家看看,可以看出,二进制当中所有引用到的动态库都放在Load commands段当中,所以,通过给这个段增加记录,就可以注入我们自己写的动态库了
- 我们自己写的代码如何新增执行的入口?
我们还需要一个”main”函数来执行我们自己的代码,这个”main”函数在oc里面称为构造函数,只要在函数前声明 “attribute((constructor)) static” 即可,
#import "CaptainHook.h"
static __attribute__((constructor)) void entry(){
// NSLog(@"\n ?!!!congratulations!!!?\n?----------------insert dylib success----------------?");
//
// [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
//
// CYListenServer(6666);
// }];
}
1.3 注入的小结
把一个自己的dylib放到APP的目录下,然后修改二进制文件,以让APP加载这个动态库。这个动态库也是需要签名的,使用对app重签名的方式对这个动态库进行签名。
动态库的注入,可以使用这个工具 insert_dylib脚本.
insert_dylib --all-yes @executable_path/test.dylib Payload/WeChat.app/WeChat
1.4重签名 二次打包
- 对app进行重签名:
codesign -f -s "iPhone Distribution: xxxx..." --entitlements Entitlements.plist Payload/wework.app
- 打包APP :
xcrun -sdk iphoneos PackageApplication -v Payload/wework.app -o ~/xxx.ipa
- 辅助命令
# 查看当前系统中可用的所有签名证书
security find-identity -v -p codesigning
# 签名, 可以加 -f 参数 以覆盖签名
codesign -s 'iPhone Developer: Thomas Kollbach (7TPNXN7G6K)' Example.app
# 查看签名状态
codesign -vv -d Example.app
# 另外一种方式来查看签名
ldid -e Demo.app/demo
II、iOS逆向分析方法
2.1 网络分析
通过分析和篡改接口数据,可以有效的破解通过接口数据来控制客户端行为的app,
- 常用的抓包工具有:
Tcpdump, WireShark, Charles;windows平台有fidller
2.2 静态分析
通过砸壳、反汇编、classdump头文件等技术来分析app行为,通过这种方式可以有效的分析出app实用的一些第三方库,甚至分析出app的架构等内容,
- 常用的工具有dumpdecrypted(砸壳)、hopper disassembler(反汇编)、class_dump(导头文件)
2.3 动态分析
动态分析指的是通过分析app的运行时数据,来定位注入点或者获取关键数据
- 常用的工具有cycript(运行时控制台)、 lldb+debugserver(远程断点调试)、logify(追踪)
control+D,来退出Cydia.
2.3.1 Logify
Logify.pl脚本在你安装theos的时候就自带:/opt/theos/bin/logify.pl
神器Logify了,它是theos的一个模块,作用就是根据头文件自动生成tweak,生成的tweak会在头文件的所有方法中注入NSLog来打印方法的入参和出参,非常适合追踪方法的调用和数据传递
III 、see also
3.1 dylib 在theos的目录
/Users/devzkn/code/taokeSearchtweak/taokesearchtweak/.theos/obj/debug
3.2 查看依赖的库
`devzkndeMacBook-Pro:debug devzkn$ otool -L taokeSearchTweak.dylib
`
devzkndeMacBook-Pro:debug devzkn$ otool -L taokeSearchTweak.dylib
taokeSearchTweak.dylib (architecture armv7):
/Library/MobileSubstrate/DynamicLibraries/taokeSearchTweak.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.55.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1349.56.0)
/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.50.2)
taokeSearchTweak.dylib (architecture arm64):
/Library/MobileSubstrate/DynamicLibraries/taokeSearchTweak.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.55.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1349.56.0)
/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.50.2)
Theos会在编译动态库时, 会这个动态库添加上这一条依赖,所以要想在非越狱环境上运行,还得把CydiaSubstrate库也跟着打包到APP中.
- 当然Theos提供了解决方案 :
在Makefile里Tweak_Name=XXXX下添加以下两行 :
SUBSTRATE ?= yes
instance_USE_SUBSTRATE = $(SUBSTRATE)
把上面的instance替换成你的TweakName,在上面的这个例子中就是XXXX
然后打包使用命令:
`make SUBSTRATE=no
`这样Theos打包的时候,会将依赖的CydiaSubstrate中的符号加载到最终生成的动态库中,不再依赖CydiaSubstrate库.
3.3 logos 语法
%hook Springboard
// overwrite methods here
%end
%hook后面跟的是你要hook的类名称,以一个%end结尾。
`%orig
`当在一个method内部的时候,%orig会调用原来的方法(original method)。
- Building, Packaging, Installing.依次执行下面的命令即可
make, make package, make install