iOS 逆向工程 ---OS 工具(Theos)

2,923 阅读4分钟
原文链接: www.jianshu.com

简介

特点:下载安装简单,Logos语法简单,编译发布简单

注意:另一个越狱工具iOSOpenDev被整合到了Xcode中,Theos并未整合到Xcode中

安装

  1. 安装Command Line Tools
    如果你的Mac安装了Xcode将会附带Command Line Tools,如果装了多个Xcode需要为Theos指定一个默认的Xcode。
    命令如下:
    $ sudo xcode-select -s /Applications/XcodeName/Contents/Developer (指定XcodeName为默认的Xcode)

  2. 下载Theos
    GitHub传送门:

    $ export THEOS=/opt/theos
    $ sudo clone git://github.com/DHowett/theos.git $THEOS
  3. 配置ldid
    ldid是专门用来签名iOS可执行文件的工具,用以在越狱iOS中取代Xcode自带的codesign。
    (ldid下载地址)下载ldid,放在/opt/theos/bin/目录下,并执行命令:
    $ sudo chmod 777 /opt/theos/bin/ldid
  4. 配置CydiaSubstrate
    首先运行Theos的自动化配置脚本:
    $ sudo /opt/theos/bin/bootstrap.sh substrate
    由于Theos存在一个bug,无法自动生成一个有效的libsubstrate.dylib文件,我们需要手动进行添加:
    • 在越狱手机中的Cydia中搜索安装CydiaSubstrate;
    • 在电脑中使用PP助手等手机文件助手找到文件CydiaSubstrate并且拷贝;
    • 将其重命名为libsubstrate.dylib后放到/opt/theos/lib/目录中。
  5. 配置dpkg-deb
    (dm.pl下载地址)下载dm.pl,并重命名为dpkg-deb后,放到/opt/theos/bin/目录下,然后执行命令:
    $ sudo chmod 777 /opt/theos/bin/dpkg-deb
  6. 配置Theos NIC templates
    Theos NIC templates内置了5种Theos工程类型的模板,还可以在(模板下载地址)中下载更多模板,解压后放到/opt/theos/templates/iphone/目录下。

使用

  1. 创建工程

    • 在终端中进入到工作目录,并执行命令:
      $ /opt/theos/bin/nic.pl
    • 选择模板类型为tweak的数字
    • 输入tweak的工程名称
    • 输入deb包的名字(类似于 bundle identifier)
    • 输入tweak作者的名字
    • 输入“MobileSubstrate Bundle fileter”,即tweak作用对象的bundle identifier,例如:
      $ com.apple.springboard
    • 输入tweak安装完成后需要重启的应用,以进程名表示,例如:
      $ SpringBoard
  2. 定制工程文件
    工程目录下应该含有以下几个文件:Makefile、Tweak.xm、control、iOSREProject.plist、theos -> /opt/theos;(其中theos指到了/opt/theos下)
    Makefile
    指定工程用到的文件、框架、库等信息,将整个过程自动化。
    Tweak.xm
    .x代表源文件支持Logos和C语法;
    .xm说明源文件支持Logos和C/C++语法。
    control
    记录了deb包管理系统所需的基本信息,会被打包进deb包里。
    主要内容:

    Packages字段:用于描述deb包的名字,可以更改。
    Name字段:用于描述工程的名字,可以更改。
    Depends字段:用于描述这个deb包的“依赖”,可以填写固件版本或其他程序,可以更改。
    Version字段:用于描述这个deb包的版本号,可以更改。
    Architecture字段:用于描述deb包安装的目标设备架构,不要更改。
    Description字段:用于描述deb包的简单介绍,可以更改。
    Maintainteer字段:用于描述deb包的维护人,可以更改。
    Author字段:用于描述tweak的作者,可以更改。
    Section字段:用于描述deb包所需的程序类别,不要更改。

    iOSREProject.plist
    记录了一些配置信息,描述了tweak的作用范围。
    iOSREProject.plist的最外层是一个字典,含有键Fileter,Fileter下是一系列数组,分为:

    Bundles:指定若干bundle为tweak的作用对象。
    Classes:指定若干classtweak的作用对象。
    Executables:指定若干可执行文件为tweak的作用对象。

    注意:当Filter下有不同类的数组时,需要添加一个”Mode : Any"键值对,当数组只有一类时,不需要添加


编译+打包+安装

  1. 编译
    $ cd theos工程目录
    $ make (此时在工程目录下,多了一个obj文件夹,里面会有一个.dylib文件,比较重要)
  2. 打包
    $ make package (此时,会生成一个deb文件,即可以发布的安装包,另外会生成一个“_"文件夹)
    $ make package messages=yes (查看生成deb详细信息)
    注意:libsubstrate.dylib需要替换并且赋予权限
    dpkg-deb需要添加,并赋予权限

  1. 安装
    1. 利用ifile安装。
    2. 命令行安装:使用ssh命令安装。(需要在Makefile中修改iOS IP为本机ip,然后执行命令:$ make package install)

Logos基本语法

  • %hook
    指定需要hook的class,必须以%end结尾。
    例:
    %hook SpringBoard
    -(void)_menubuttonDown:(id)down {
        NSLog(@"You've pressed home button.");
        %orig;//call the original _menuButtonDown;
    }
    %end
  • %log
    在%hook内部使用,将函数的类名、参数等信息写入syslog。
    例:
    %hook SpringBoard
    -(void)_menubuttonDown:(id)down {
        %log((NSString *)@"iOSRE",(NSString *)@"Debug");
        %orig;//call the original _menuButtonDown;
    }
    %end
  • %orig
    在hook内部使用,执行被hook的函数的原始代码。
    例:
    %hook SpringBoard
    -(void)_menubuttonDown:(id)down {
        NSLog(@"You've pressed home button.");
        %orig;//call the original _menuButtonDown;
    }
    %end
    如果去掉%orig,那么原始函数将不会得到执行。
    %orig还可以用来更改原始函数的参数。
    例:
    %hook SBLockScreenDateViewController
    -(void)setCustomSubtitleText:(id)arg1 withColor:(id)arg2 {
        %orig(@"iOS 8 App Reverse Engineering",arg2);
    }
    %end
    //这个方法会改变锁屏界面的日期显示
  • %group
    将%hook分组,便于代码管理和按条件初始化分组,必须以%end结尾,一个%group可以包含多个%hook,所有属于未自定义的%group的%hook会被自动归类到%group _ungrouped中。
    例子:
    %group iOS7Class
    %hook SpringBoard
    -(void)_menubuttonDown:(id)down
    {
        NSLog(@"You've pressed home button.");
        %orig;//call the original _menuButtonDown;
    }
    %end
    %end
  • %init
    用于初始化某个%group,必须在%hook或%ctor内调用;
    可以指定需要初始化的%group,否则将会初始化_ungrouped。
  • %ctor
    tweak的constructor,完成初始化工作,如果不执行%ctor默认会生成一个%ctor并调用%init(_ungrouped),如果执行%ctor,则必须执行%init(group/_ungrouped)。
    例子:
    %group iOS7Class
    %hook SpringBoard
    -(void)_menubuttonDown:(id)down
    {
        NSLog(@"You've pressed home button.");
        %orig;//call the original _menuButtonDown;
    }
    %end
    %end
    %ctor
    {
        %init(iOS7Class);
    }
    //%ctor不需要以%end结尾
  • %new
    在%hook内部使用,给一个现有class添加新函数。
  • %c
    动态获取一个类的定义,在%hook或%ctor内使用。