iOS逆向之Theos基础到实战

Theos是一个越狱开发工具包,Theos是越狱开发工具的首先,因为其最大的特点就是简单。大道至简,Theos的下载安装、编译发布都比较简单,越狱开发中另一个常用的工具是iOSOpenDev,因为本篇的主题是Theos,所以对iOSOpenDev不做过多赘述。本篇博客的主题是Thoes的安装及其使用。

Theos的配置与安装

Theos的配置与安装算是比较简单的,Theos的官方文档地址官方Wiki,当然进行该部分操作时,要保证你本地已经安装了Homebrew.

1
2
3
4
5
# 官方推荐安装到/opt/目录下
export THEOS=/opt/theos
# 如果之前已经安装过 theos,请先删除,然后下载最新版
rm -rf $THEOS
sudo git clone --recursive https://github.com/theos/theos.git $THEOS

下载好Theos后,要修改一下文件的权限,如下命令

1
sudo chown (id−u):(id−u):(id -g) theos

至此,Theos安装完毕

配置 dpkg-deb

deb 是越狱开发安装包的标准格式,而 dpkg-deb 是操作 deb 文件的工具,有了这个工具,Theos 才能将工程正确地打包成 deb 包。

https://raw.githubusercontent.com/DHowett/dm.pl/master/dm.pl下载dm.pl,将其重命名为 dpkg-deb 后,放到 /opt/theos/bin/ 目录下

安装ldid

在Theos开发插件中,iOS文件的签名是使用ldid工具来完成的,也就是说ldid取代了Xcode自带的Codesign。下方就是ldid的安装过程。

1
brew install ldid

Theos创建deb包

1
$THEOS/bin/nic.pl

接下来我们就要使用theos来创建我们的工程了,创建工程也是比较简单的,就是调用我们theos目录中bin下的nic.pl命令。具体执行如下所示。在执行nic.pl命令后,会让你选择新建工程的模板,目前theos中内置的是12套模板,当然你可以从网上下载其他的模板。当然我们此处创建的是application_modern类型的工程,所以我们就选2即可,当然,如果你想创建tweak,那么就选11即可,下方我们选择的是第二个模板。

在选择模板后,紧接着会让你做一系列的操作,这一些列的操作和Xcode新建iOS工程的步骤类似。

(1)输入你的工程的名字(Project Name,必选项),此处我们工程的名字是FirstTheosApplication。

(2)输入包名(Package Name),包名的命名规则一般是你们公司域名的倒写,然后后边加上你的工程名字,此处我就随便写了一个,就是下方的com.ludashi.firsttheosapplication。

(3)输入作者的名字(Author/Maintainer Name), 此处我们输入的是Mr.LuDashi

(4)然后如数类名的前缀(Class name prefix), 此处我们输入的是CE。

经过上述配置后,我们的工程就创建好了。

下方是我们创建后的工程文件目录,当然packages文件夹是我们编译打包后才生成的文件,其中的deb就是我们的安装文件。可以将该安装包安装到我们的越狱手机上。

接着我们要做一些编译打包前的准备工作,SDKVERSION是编译工程时所使用的SDK,因为本机Xcode中是9.3的SDK,所以我们知道的SDKVERSION是9.3。指定完编译所需的SDK后,我们需要指定打包后的文件所安装设备的IP地址,使用THEOS_DEVICE_IP来指定。下方的IP地址是一个越狱手机的IP地址。

在指定这个设备IP之前,你要保证你的越狱设备安装了OpenSSH,并且可以在Mac的终端上进行ssh登录。

编译打包前的准备工作

1
2
export SDKVERSION=9.3
export THEOS_DEVICE_IP=ios设备的ip

进行编译

做好编译前的准备工作后,紧接着就是编译我们刚才创建的工程了。首先进入到我们的firsttheosapplication目录中,执行make命令进行编译.

1
2
cd firsttheosapplication
make

进行打包

1
make package

Snip20170512_6

安装

1
make install

从Cydia中进行查看

下方就是我们项目安装后的效果。打开Cydia,选择已安装Tab, 会看到我们刚才安装的FirstTheosApplication(实用工具),我们可以点进去进行查看,其中的一些信息大部分是我们刚才配置的信息。到此我们一个完整的流程就走完了。

Theos创建Tweak工程

下方就是我们Tweak工程的创建,与上述工程的创建类似,不过我们在此选择的是Tweak模板。如下所示,我们将该Tweak工程命名为LockScreenAlter,其他配置项使用默认值即可。然后进入到我们的LockScreenAlter工程目录中,主要有下方四个文件。
Tweak工程创建

Makefile文件

该文件类似于配置文件,用来指定工程用到的文件、框架、库、使用的SDK等等,将整个编译、打包、安装的过程进行自动化。下方就是我们Makefile中的内容,下方红框中是创建完工程后默认的配置,上面红框中是后来我们添加的配置。这些项指定了编译、安装时所需的参数,使其自动化

Tweak.xm文件的编写

分析这一步是至关重要的,因为这一步可以让你明白你的代码作用于何处。因为我们要在锁屏的页面进行弹框,所以我们要在相应的锁屏页面添加hook。下方就是我们的分析过程。经过浏览系统的头文件,我们从下方路径中找到了SBLockScreenManager.h这个文件,从文件名不难推测出该文件就是负责iPhone系统锁屏的文件,于是乎我们对其进行hook实现。

下方是上述头文件的内容,从内容我们更加坚信SBLockScreenManager类就是用来管理系统锁屏的,因为其中有个字段是用来表示是否已经锁屏的isUILocked。该头文件中还有一个类方法和一个对象方法。当然这个类方法明眼一看就是用来获取该类的单例的。而对象方法lockUIFromSource……应该是用来锁屏和解锁的。于是乎想要在锁屏中弹框就要在SBLockScreenManager类中的唯一的对象方法中进行操作了。

下方就是在Tweak.xm中的所有代码。是Logos语法,使用起来是比较简单的。%hook与%end成对出现,%hook后方跟的是我们要修改的类名,此处我们要对SBLockScreenManager进行修改,类似于OC中的继承操作。%orig,用来执行修改函数的原始函数,此处可以看做是OC语法中的super,类似于调用父类的方法。下方代码就用到这些Logos语法就足以在锁屏出进行弹框了。

常用Logos语法简介:

1
2
3
4
5
6
7
8
%hook 指定需要hook的类名,以%end结尾
%log 用来打印log的,将信息输入到syslog中,如%log((NSString *)@"ZeluLi")
%orig 执行被hook函数的原始代码,类似于super.method功能
%group 该指令用于%hook的分组,%group后边跟的是组名,%group也是必须以%end结尾,其中可以包含多个%hook
%init 该指令用来初始化某个%group,一个group只有被初始化后才可生效,init必须在hook中进行执行。
%ctor tweak的构造器,用来初始化,如果不显式定义,Theos就会自动生成一个%ctor,并在其中调用%init(_ungrouped). 如:%ctor { %init(_ungrouped)}
%new 该指令用来给现有的class添加一个新的函数。与Runtime中的class_addMethod相同。
%c 该指令用来获取一个类的名称,类似于objc_getClass。

上述就先涉及这么多,更详细的请参加:http://iphonedevwiki.net/index.php/Logos

control文件

control文件中存储的内容记录了deb包管理系统所需的基本信息,会被打包进deb包里。下方就是control中内容,其中存储的就是一些包名、工程名、版本、作者等等,与打包安装后在Cydia中看到的信息相同。

进行编译、打包、安装

编译打包安装的过程与上一部分类型,在此就只展示一下过程,不做过多赘述了。

  • 编译 make
  • 打包make package
  • 安装到手机make install

从Cydia中进行查看

下方就是我们成功安装后在Cydia中查看的截图,安装成功后,当你锁屏时就会弹出一个Alter。

免越狱安装注入dylib的App

生成dylib

创建完Tweak工程编译后,在.theos文件层级下面生成了dylib文件
Snip20170512_8

检查依赖

1
otool -L Test.dylib

Snip20170512_10
这里有对CydiaSubstrate的依赖 , 这是不行的 , 这个是theos在越狱机上特有的, 在非越狱机上需要更改此依赖

首先要找到libsubstrate.dylib文件,该文件应该在/opt/thoes/lib/目录下,没有了点击libsubstrate下载,然后将其拷贝到与你生成的的.dylib一个目录下,通过下面的指令修改依赖

1
install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/libsubstrate.dylib Test.dylib

然后重新查看Test.dylib
会发现依赖已经被修改完毕
Snip20170512_11

获取砸壳版本的微信 ipa

因为在 AppStore 上面下载得到的应用都是经过加密的,可以执行文件上已经被加过一层壳,所以我们需要先拿到砸过壳版本的微信应用。
有两种方法:

  1. 直接在 PP 助手下载
  2. 使用 Clutch 对越狱手机上应用进行砸壳
  3. dumpdecrypted,使用方法请参考博客

第一种方法没什么好说的,这里主要讲讲第二种方法。
首先,将 Cluth 仓库 clone 到本地

1
2
git clone https://github.com/KJCracks/Clutch
cd Clutch

接着,使用 Xcode 进行构建,得到可执行文件:

1
xcodebuild -project Clutch.xcodeproj -configuration Release ARCHS="armv7 armv7s arm64" build

生成出来的可执行文件就在 Clutch 目录下,将其拷贝到手机上:

1
scp Clutch/clutch root@<your.device.ip>:/usr/bin/

之后,就可以使用这个工具来进行砸壳了。

先 ssh 到越狱手机上,然后列出当前安装的应用:

1
2
3
4
5
6
ssh root@<your.device.ip>
clutch -i
# Installed apps:
# 1: WeChat <com.tencent.xin>
# 2: DingTalk <com.laiwang.DingTalk>
# 3: 喜马拉雅FM(听书社区)电台有声小说相声英语 <com.gemd.iting>

可以得到 clutch 把相应的包名也显示出来了,这时我们就可以进行砸壳了:

1
2
3
4
5
6
7
8
9
clutch -d com.tencent.xin
# com.tencent.xin contains watchOS 2 compatible application. It's not possible to dump watchOS 2 apps with Clutch 2.0.4 at this moment.
# Zipping WeChat.app
# Swapping architectures..
# ASLR slide: 0xb3000
# ...
# writing new checksum
# DONE: /private/var/mobile/Documents/Dumped/com.tencent.xin-iOS7.0-(Clutch-2.0.4).ipa
# Finished dumping com.tencent.xin in 76.9 seconds

可以看到,clutch 将砸过后的 ipa 文件放到了 /private/var/mobile/Documents/Dumped/ 目录下。

我们将它改成一个比较简单的名字,然后拷回电脑上:

1
2
mv /private/var/mobile/Documents/Dumped/com.tencent.xin-iOS7.0-\(Clutch-2.0.4\).ipa /private/var/mobile/Documents/Dumped/wechat.ipa
scp root@<your.device.ip>:/private/var/mobile/Documents/Dumped/wechat.ipa ~/Desktop

将动态链接库注入二进制文件中

接下来,就需要将我们的库注入到微信的二进制文件中,可以使用开源的 optool 工具。

编译安装 optool 工具:

1
2
3
4
因为 optool 添加了 submodule,因为需要使用 --recuresive 选项,将子模块全部 clone 下来
git clone --recursive https://github.com/alexzielenski/optool.git
cd optool
xcodebuild -project optool.xcodeproj -configuration Release ARCHS="x86_64" build
1
如果碰到类似 “error: There is no SDK with the name or path ‘/path/to/optool/macosx10.9’” 的错误,请使用 Xcode 打开工程,在 Build Setting 中选择正确的 SDK 版本。

将砸壳过的 ipa 文件解压,然后将 libsubstrate.dylib 与 Test.dylib 拷贝到解压后的WeChat.app 目录下。

1
2
# cd 到Test.dylib同级目录
cp libsubstrate.dylib Test.dylib /Users/shmily/test/.theos/obj/debug/微信-6.5.7\(越狱应用\)/Payload/WeChat.app

Snip20170512_12

使用 optool 把 Test.dylib 注入到二进制文件中:

1
optool install -c load -p "@executable_path/Test.dylib" -t /Users/shmily/test/.theos/obj/debug/微信-6.5.7\(越狱应用\)/Payload/WeChat.app/WeChat

Snip20170512_13

1
2
在开始打包之前,请先将 WeChat.app 里面的 Watch 目录删除,这个目录是跟 Watch 有关的,如果不删除的话,会导致后继的安装步骤出问题。
出现 A WatchKit app within this app is not a valid bundle 的错误。

打包并重签名

打包 ipa 与重签名可以直接使用图形化工具 ios-app-signer 来完成。

这个工具可以自动加载出本机的证书以及 Provisioning Profile 文件,使用起来十分方便,当然也可以手动选择证书文件。

Snip20170512_14

点击 start 后,指定保存路径,iOS App Signer 就会帮你搞定所有事情。

安装

在 iOS App Signer 完成打包与重签名后,我们就可以进行安装了。

安装有两种方法,一种是使用 iTool 工具安装 ipa 文件(测试安装失败)。

另外一种是针对有 XCode 的同学,在菜单 - Window - Devices 中打开设置窗口。点击 Installed Apps 栏下面的 + 号就可以选择 ipa 文件进行安装了(这个可以用)。

效果

重签名后的应用由于与原应用的 Bundle id 是不同的,所以可以同时安装两个应用。这也就是淘宝上所谓的微信多开的原理。

小结

我们最终得到了一个可以安装在免越狱设备上的微信 ipa 文件,但是这些步骤对于有些来说,可能还是太过复杂了。他们需要的只是重签名过的 ipa 文件,但是很可惜,由于我是使用的个人证书打包的,所以无法直接将 ipa 文件发出来。

如果有哪位好心的小伙伴可以贡献一个企业证书的话,我就可以利用这个企业证书打个包,然后直接进行应用分发,这也许就是最方便快捷的方法了。

iOS逆向工程之Theos-青玉伏案的博客

移动App入侵与逆向破解技术-iOS篇

免越狱版 iOS 抢红包插件