TheOS 被设计为一个在基于 Unix 平台 (Mac OS X、IOS…) 和大多数 的Linux 平台下开发 iOS 程序的集成开发环境。说是集成开发环境,其实就是给我们准备好了一些代码模板、预置一些基本的 Makefile 脚本,我们还是要在 终端命令行 中完成一些关键操作。

1.安装和配置

第一步:安装 dpkg 和 LDID。

brew install dpkg ldid

第二步:安装 TheOS。

sudo git clone --recursive https://github.com/theos/theos.git /opt/theos

指令中的 --recursive ,表示递归执行。

第三步:配置权限。

sudo chown $(id -u):$(id -g) /opt/theos

第四步:配置环境变量。修改 bash_profile 文件,在文件中添加两行: THEOS 目录 和 bin。

export THEOS=/opt/theos
export PATH=/opt/theos/bin/:$PATH

【说明】:环境变量配置,可以查看OS X修改环境变量

2.使用Theos

2.1创建工程

在终端输入如下指令:

nic.pl

如果提示如下错误:

执行以下指令即可:

source .bash_profile

执行完“nic.pl”指令后,会出现如下选择模板的界面:

在逆向工程的初级阶段,所开发程序的主要类型是 tweak,因此输入 15,按 Enter 键继续。接下来和 Xcode 创建工程一样,会有一系列的步骤:

  1. 输入工程名字(Project Name (required),必填项);
  2. 输入包名(Package Name [com.yourcompany.helloworld]);
  3. 输入作者的名字(Author/Maintainer Name [LeeGof]);
  4. 要注入程序的BundleID(MobileSubstrate Bundle filter [com.apple.springboard]):要注入程序的BundleID,默认的进程为com.apple.springboard,为了演示方便,在此先使用默认进程作为注入对象。

2.2工程文件说明

Tweak 工程新建完成后,其工程目录下的文件,主要有 4 个:

2.2.1 control 文件

该文件记录了工程的基本信息,会被打进 deb 包中,字段内容如下:

Package: com.gof.-
Name: GofWechat
Depends: mobilesubstrate
Version: 0.0.
Architecture: iphoneos-arm
Description: An awesome MobileSubstrate tweak!
Maintainer: LeeGof
Author: LeeGof
Section: Tweaks
  • Package 字段:用于描述这个 deb 包的名字,采用的命名方式和 bundle identifier 类似,可以按需更改;
  • Name 字段:用于描述这个工程的名字,可以按需更改;
  • Depends 字段:用于描述这个 deb 包的“依赖”。“依赖”指的是这个程序运行的基本条件,可以填写固件版本或其他程序,如果当前 iOS 不满足“依赖”中所定义的条件,则此 tweak 无法正常工作,可以按需更改。例如:
Depends: mobilesubstrate, firmware (>=9.0)

表示当前iOS版本必须在 9.0 以上,且必须安装 MobileSubstrate,才能正常运行这个 tweak。

  • Version 字段:用于描述这个 deb 包的版本号,可以按需更改;
  • Architecture 字段:用于描述 deb 包安装的目标设备架构,不要更改
  • Description 字段:deb 包的简单介绍,可以按需更改;
  • Maintainer 字段:用于描述 deb 包的维护人,即 deb 包的制作者而非 tweak 的作者,可以按需更改;
  • Author 字段:用于描述 tweak 的作者,可以按需更改;
  • Section 字段:用于描述 deb 包所属的程序类别,不要更改

control 文件中可以自定义的字段还有很多,一般上面的信息就已经足够了。更全面的可以查看官方网站:http://www.debian.org/doc/debian-policy/ch-controlfields.html。值得注意的是:Theos 在打包 deb 时会对 control 文件做进一步处理。比如更改 Version 字段为:0.0.1-2,标识 Theos 的打包次数,方便管理;增加 Installed-Size 字段,用于描述 deb 包安装后的估算大小,与实际大小可能有偏差,不要更改。

2.2.2 Makefile

该文件用来指定工程编译和链接要用到的文件、框架、库等信息,将整个过程自动化,字段内容如下:

export THEOS_DEVICE_IP=127.0.0.1
export THEOS_DEVICE_PORT= include $(THEOS)/makefiles/common.mk TWEAK_NAME = GofWechat
GofWechat_FILES = Tweak.xm
GofWechat_CFLAGS = -fobjc-arc include $(THEOS_MAKE_PATH)/tweak.mk after-install::
install.exec "killall -9 SpringBoard"
  • 前面两行配置了 USB 连接对应的 IP 和 端口,根据实际情况配置;
  • 第 3 行的 include 字段指定了工程的 common.mk 文件,固定写法,不要修改
  • TWEAK_NAME 字段填入的是建立工程时命令行输入的 Project Name,与 control 文件中的“Name”字段对应,不要更改
  • GofWechat_FILES 字段指定工程包含的源文件,如果工程中需要用到多个源文件则用空格将各个文件名分开,可以按需更改;
  • include 字段指定工程的 mk 文件,这里新建的是 tweak 工程,所以填入的是 tweak.mk 文件,还可以根据需求填入 application.mk 以及 tool.mk 文件;
  • 最后一行 after-install 字段指定安装程序后需要执行的操作,这里注入 Wechat 进程并执行自己的代码,需要重启 SpringBoard进程,好让 MobileSubstrate 加载对应的 dylib。

Makefile文件除了自动生成的这些字段外,还可以根据功能手动添加其他字段:

  • ARCHS 字段可以用来指定处理器架构,一般情况下填写“ARCHS = armv7 arm64”即可;
  • TARGET 字段用来指定SDK版本,例如:
TARGET = iphone:7.0
  • framework 字段可以指定要导入的框架,比如 “GofWechat_FRAMEWORKS = UIKit”,可以导入 UIKit 框架,另一方面,还可以通过 GofWechat_PRIVATE_FRAMEWORKS 字段指定要导入的私有库,格式不变。例如:
GofWechat_FRAMEWORKS = UIKit CoreTelephony CoreAudio
GofWechat_PRIVATE_FRAMEWORKS = AppSupport ChatKit

2.2.3 GofWechat.plist

plist 文件记录工程的配置信息,主要作用是指定程序的作用范围,内容如下:

从上面可以看到,该文件的内容是一系列的 Dictionary,最外层为 Root 键,Root 键下为 Filter 键,Filter 键下的 array 即为要设置的部分。该部分分为三类:

  • 第一类是 Bundles,即所编写程序的作用对象,这个类型的字段就是所要注入的程序 Bundle 名,这里要注入的进程为 Wechat,所以填写 com.tencent.xin,可以指定多个作用对象;
  • 第二类是 Classes,即指定要注入的类名,同样是根据填入的字符串来筛选注入的类名;
  • 第三类是 Executables,即指定要注入的可执行文件名。

这三类 Array 可以根据需要来设定。但按照混合配置方式,一个文件只有满足 Filter 中所有 Array 下的至少一个条件,tweak 才能生效。这样显然不合理。所以额外有一个 Mode 键,将其值设置为 Any,那么文件满足 Filter 中的任一条件就能成为 tweak 的作用对象。

当 Filter 下的 array 只有一类时,不需要添加 Mode 和 Any 键值对。

2.2.4 Tweak.xm

该文件是实现具体功能的关键所在,是实现具体功能的源文件,这个文件支持 Logos 和 C、C++ 语法。文件内容如下:

/* How to Hook with Logos
Hooks are written with syntax similar to that of an Objective-C @implementation.
You don't need to #include <substrate.h>, it will be done automatically, as will
the generation of a class list and an automatic constructor. %hook ClassName // Hooking a class method
+ (id)sharedInstance {
return %orig;
} // Hooking an instance method with an argument.
- (void)messageName:(int)argument {
%log; // Write a message about this call, including its class, name and arguments, to the system log. %orig; // Call through to the original function with its original arguments.
%orig(nil); // Call through to the original function with a custom argument. // If you use %orig(), you MUST supply all arguments (except for self and _cmd, the automatically generated ones.)
} // Hooking an instance method with no arguments.
- (id)noArguments {
%log;
id awesome = %orig;
[awesome doSomethingElse]; return awesome;
} // Always make sure you clean up after yourself; Not doing so could have grave consequences!
%end
*/

以上的注释展示了基本的Logos语法,具体可以分为三类:

  • 第一类是 %hook 和 %end,其中 %hook 后面指定要 hook 的类名,另一方面,hook 的整块逻辑完成后结尾要加上 %end,在 hook 逻辑中可以添加要 hook 的函数,并在函数体内部实现想要添加的代码逻辑;
  • 第二类是 %orig,该语句代表执行原函数逻辑,即完成 hook 操作后可以选择是否调用原函数的代码,若需要调用则加上“%orig;”即可;
  • 第三类是 %log,这类代码的作用是在 log 中打印 hook 的函数的类名、参数等信息。

除了注释中展示的三种语法外,Logos 还支持 %group、%init、%ctor 等语法,更多的 Logos 语法可查看这篇文章

这里我们 Hook 微信的登录按钮事件,获取密码并打印,代码如下:

%hook WCAccountLoginLastUserViewController

- (void)onNext{
UIView *view = MSHookIvar<UIView *>(self,"m_passwordView");
UITextField *tfPwd = view.subviews[].subviews[].subviews[];
//NSLog(@"\nLeeGof 密码:%@", tfPwd.text);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Gof" message:tfPwd.text delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alert show]; //%orig;
} %end

2.3编译&打包&安装

2.3.1编译

Theos 采用与 debian 相同的 make 命令来编译 Theos 工程。执行如下指令:

~/Desktop/GofWechat/gofwechat > make
> Making all for tweak GofWechat…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (armv7)…
==> Linking tweak GofWechat (armv7)…
ld: warning: building for iOS, but linking in .tbd file (/opt/theos/vendor/lib/CydiaSubstrate.framework/CydiaSubstrate.tbd) built for iOS Simulator
==> Generating debug symbols for GofWechat…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (arm64)…
==> Linking tweak GofWechat (arm64)…
ld: warning: building for iOS, but linking in .tbd file (/opt/theos/vendor/lib/CydiaSubstrate.framework/CydiaSubstrate.tbd) built for iOS Simulator
==> Generating debug symbols for GofWechat…
rm /Users/GofLee/Desktop/GofWechat/gofwechat/.theos/obj/debug/arm64/Tweak.xm.mm
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (arm64e)…
==> Linking tweak GofWechat (arm64e)…
ld: warning: building for iOS, but linking in .tbd file (/opt/theos/vendor/lib/CydiaSubstrate.framework/CydiaSubstrate.tbd) built for iOS Simulator
==> Generating debug symbols for GofWechat…
rm /Users/GofLee/Desktop/GofWechat/gofwechat/.theos/obj/debug/arm64e/Tweak.xm.mm
==> Merging tweak GofWechat…
==> Signing GofWechat…

从上面的输出结果可以看到,Theos 完成了预处理、编译、签名等一系列操作,此时目录下多了一个 .theos 文件夹。在这个目录下,有一个文件:.theos/obj/debug/GofWechat.dylib,这个文件实际上是编译之后生成的动态库。

这里有一个注意点:路径只能是英文,如果是中文的话,有可能会报错失败。

2.3.2打包

使用如下指令打包:

~/Desktop/GofWechat/gofwechat > make package
> Making all for tweak GofWechat…
make[]: Nothing to be done for `internal-library-compile'.
> Making stage for tweak GofWechat…
dm.pl: building package `com.gof.-:iphoneos-arm' in `./packages/com.gof.-_0.0.1-1+debug_iphoneos-arm.deb'

命令执行完成后,目录下多了一个 packages 文件夹,里面有一个 deb 文件,这是安装到手机上的插件格式,它和编译阶段生成的 .theos/obj/debug/GofWechat.dylib 关联。

有时候可能遇到如下所示错误信息:

解决方法:修改 opt/theos/makefiles/package/deb.mk 文件的第六行:

将 THEOSPLATFORM_DPKG_DEB_COMPRESSION ?= lzma,最后的 lzma 改成 xz 就可以了。

2.3.3安装

执行指令:

~/Desktop/GofWechat/gofwechat > make package install
> Making all for tweak GofWechat…
make[]: Nothing to be done for `internal-library-compile'.
> Making stage for tweak GofWechat…
dm.pl: building package `com.gof.-:iphoneos-arm' in `./packages/com.gof.-_0.0.1-3+debug_iphoneos-arm.deb'
==> Installing…
Selecting previously unselected package com.gof.-.
(Reading database ... files and directories currently installed.)
Preparing to unpack /tmp/_theos_install.deb ...
Unpacking com.gof.- (0.0.-+debug) ...
Setting up com.gof.- (0.0.-+debug) ...
install.exec "killall -9 SpringBoard"

可以看到已经成功安装。这时候我们打开 Cydia,可以看到在 Cydia 中有了我们自己定义的插件:

安装成功后,打开微信,输入密码,点击登录,可以看到我们写的 Alert 框,正常弹出了。这里,大家可能会好奇:我们写的这个插件,是在设备的哪里安装的?

我们可以把移动设备中的微信可执行文件导出,可以看到 Mach-O 文件并没有做修改。那这个动态库是怎么生效的呢?微信在启动时,dyld 根据 DYLD_INSERT_LIBRARIES 环境变量进行注入的。

有时会遇到如下报错:

这种情况一般是deb.mk文件版本不正确,这里更新为下面的版本就可以了。

ifeq ($(_THEOS_PACKAGE_FORMAT_LOADED),)
_THEOS_PACKAGE_FORMAT_LOADED := 1 _THEOS_DEB_PACKAGE_CONTROL_PATH := $(or $(wildcard $(THEOS_PROJECT_DIR)/control),$(wildcard $(THEOS_PROJECT_DIR)/layout/DEBIAN/control))
_THEOS_DEB_CAN_PACKAGE := $(if $(_THEOS_DEB_PACKAGE_CONTROL_PATH),$(_THEOS_TRUE),$(_THEOS_FALSE)) _THEOS_DEB_HAS_DPKG_DEB := $(call __executable,dpkg-deb)
ifneq ($(_THEOS_DEB_HAS_DPKG_DEB),$(_THEOS_TRUE))
internal-package-check::
@echo "$(MAKE) package requires dpkg-deb."; exit 1
endif ifeq ($(_THEOS_DEB_CAN_PACKAGE),$(_THEOS_TRUE)) # Control file found (or layout/ found.)
THEOS_PACKAGE_NAME := $(shell grep -i "^Package:" "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-)
THEOS_PACKAGE_ARCH := $(shell grep -i "^Architecture:" "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-)
THEOS_PACKAGE_BASE_VERSION := $(shell grep -i "^Version:" "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" | cut -d' ' -f2-) $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN:
$(ECHO_NOTHING)mkdir -p "$(THEOS_STAGING_DIR)/DEBIAN"$(ECHO_END)
ifeq ($(_THEOS_HAS_STAGING_LAYOUT),1) # If we have a layout/ directory, copy layout/DEBIAN to the staging directory.
$(ECHO_NOTHING)[ -d "$(THEOS_PROJECT_DIR)/layout/DEBIAN" ] && rsync -a "$(THEOS_PROJECT_DIR)/layout/DEBIAN/" "$(THEOS_STAGING_DIR)/DEBIAN" $(_THEOS_RSYNC_EXCLUDE_COMMANDLINE) || true$(ECHO_END)
endif # _THEOS_HAS_STAGING_LAYOUT $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN/control: $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN
$(ECHO_NOTHING)sed -e '/^[Vv]ersion:/d' "$(_THEOS_DEB_PACKAGE_CONTROL_PATH)" > "$@"$(ECHO_END)
$(ECHO_NOTHING)echo "Version: $(_THEOS_INTERNAL_PACKAGE_VERSION)" >> "$@"$(ECHO_END)
$(ECHO_NOTHING)echo "Installed-Size: $(shell du $(_THEOS_PLATFORM_DU_EXCLUDE) DEBIAN -ks "$(THEOS_STAGING_DIR)" | cut -f 1)" >> "$@"$(ECHO_END) before-package:: $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN/control _THEOS_DEB_PACKAGE_FILENAME = $(THEOS_PACKAGE_DIR)/$(THEOS_PACKAGE_NAME)_$(_THEOS_INTERNAL_PACKAGE_VERSION)_$(THEOS_PACKAGE_ARCH).deb
internal-package::
$(ECHO_NOTHING)COPYFILE_DISABLE=1 $(FAKEROOT) -r dpkg-deb -Zgzip -b "$(THEOS_STAGING_DIR)" "$(_THEOS_DEB_PACKAGE_FILENAME)" $(STDERR_NULL_REDIRECT)$(ECHO_END) # This variable is used in package.mk
after-package:: __THEOS_LAST_PACKAGE_FILENAME = $(_THEOS_DEB_PACKAGE_FILENAME) else # _THEOS_DEB_CAN_PACKAGE == 0
internal-package::
@echo "$(MAKE) package requires you to have a layout/ directory in the project root, containing the basic package structure, or a control file in the project root describing the package."; exit 1 endif # _THEOS_DEB_CAN_PACKAGE
endif # _THEOS_PACKAGE_FORMAT_LOADED

也可以先将deb文件拷贝到设备,然后cd到设备对应的目录,执行如下指令:

dpkg -i *.deb

2.3.4卸载

如果需要卸载安装包,执行如下指令即可:

dpkg -r com.gof.-

iOS逆向之TheOS的更多相关文章

  1. iOS逆向系列-theos

    概述 theos是GitHub开源的一个项目,通过nic.pl创建tweak项目.通过编写我们注入代码,然后执行编译.打包.安装等操作将代码注入iPhone安装的制定程序. theos环境配置 安装签 ...

  2. iOS逆向实战与工具使用(微信添加好友自动确认)

    iOS逆向实战与工具使用(微信添加好友自动确认) 原文链接 源码地址 WeChatPlugin-iOS Mac OS 版微信小助手(远程控制.消息防撤回.自动回复.微信多开) 一.前言 本篇主要实现在 ...

  3. iOS逆向之一 工具的安装和使用

    iOS逆向之一-工具的安装和使用 最近在学习iOS安全方面的技术,有些东西就记录下来了,所有有了这篇文章.顺便也上传了DEMO,可以再这里找到这些DEMO的源码:dhar/iOSReProject 越 ...

  4. iOS逆向分析app

    适合有一定的逆向编程基础的人看. 背景:自动抢红包的脚本工具:cyscript,reveal,class-dump,越狱的pod等. 这里先上一张reveal的分析图: 小结:获取到了真个软件的整体结 ...

  5. iOS 逆向之ARM汇编

    最近对iOS逆向工程很感兴趣. 目前iOS逆向的书籍有: <Hacking and Securing IOS Applications>, <iOS Hacker's Handboo ...

  6. ios逆向过程中lldb调试技巧

    在ios逆向过程中,善于运用lldb,会给逆向带来很大的方便 一般的命令: 1.image list -o -f  看看各个模块在内存中的基址 2.register read r0  读取寄存器r0的 ...

  7. iOS逆向开发(1):基础工具 | ssh | scp | socat

    小白:小程,我一直想问,什么是逆向来着?是逆向行驶吗? 小程:理解为逆向行驶也没错.一般的项目是从无到有,而逆向是从已有的状态入手,分析出已有的流程与结构的手段. iOS上的逆向开发,是一件有趣的事情 ...

  8. iOS逆向+越狱

    感觉本文涉及内容有点多的,但是自己不愿意写太多,就简单的谢谢关于ios上手的东西吧 初级入手不免要用到,pp助手,i4 tools等 iOS逆向-ipa包重签名及非越狱手机安装多个应用 1.常识 我们 ...

  9. 偏执的iOS逆向研究员:收集全版本的macOS iOS+越狱+内核调试

    Intro 虽然“只有偏执狂才能够生存”这句话已经被假药停给毁了,但是作为一只有逼格的高大上的iOS逆向分析研究员,难道如果有现成的macOS/iOS全版本镜像可以下载并且无限“漫游”,难道你就不想来 ...

随机推荐

  1. iOS开发中didSelectRowAtIndexPath tap事件响应延迟

    为UITableViewCell添加tapped事件,代码如下: class VideoViewController: UIViewController , UITableViewDataSource ...

  2. 深度学习原理与框架-猫狗图像识别-卷积神经网络(代码) 1.cv2.resize(图片压缩) 2..get_shape()[1:4].num_elements(获得最后三维度之和) 3.saver.save(训练参数的保存) 4.tf.train.import_meta_graph(加载模型结构) 5.saver.restore(训练参数载入)

    1.cv2.resize(image, (image_size, image_size), 0, 0, cv2.INTER_LINEAR) 参数说明:image表示输入图片,image_size表示变 ...

  3. Fragment的粗浅理解

    Fragment: 1.它是对于Activity界面实现的一种途径,相对于已经绑定的Layout,他更轻便,更灵活,更具有自由度和可设计性. 2.Fragment的功能正如他的正文意思所言,他是一个片 ...

  4. unshift() 方法将一个或多个元素添加到数组的开头,并返回新数组的长度

    var arr = [1, 2]; arr.unshift(0); //result of call is 3, the new array length //arr is [0, 1, 2] arr ...

  5. java学习笔记(十):scanner输入

    可以通过 Scanner 类来获取用户的输入. 通过next()类和nextLine()类来获取字符串. 通过 Scanner 类的 next() 类来获取输入的字符串. import java.ut ...

  6. 使用Pyquery+selenium抓取淘宝商品信息

    配置文件,配置好数据库名称,表名称,要搜索的产品类目,要爬取的页数 MONGO_URL = 'localhost' MONGO_DB = 'taobao' MONGO_TABLE = 'phone' ...

  7. [leetcode]51. N-QueensN皇后

    The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...

  8. [leetcode]94. Binary Tree Inorder Traversal二叉树中序遍历

    Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] ...

  9. Linux-echo、cat命令详解(14)

    echo:显示一段文字 比如: echo hello,串口上就显示hello echo hello > /dev/tty1, LCD上便显示hello字段 cat:查看一个文件的内容 比如: c ...

  10. python 之字符编码

    一    了解字符编码的储备知识 python解释器和文件本编辑的异同      相同点:python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样 不 ...