iOS逆向工程初探一

746 阅读6分钟

文档价值

  • 掌握编码的本质,编写高效代码
  • 修改已有App的功能
  • 学习优秀App的设计
  • 增强客户端的安全性
  • 通用性极强(越底层,通用性越强)

越狱环境搭建

知识储备

  • UI界面
  • 多线程
  • 数据存储

设备

  • 调试设备 iphone
    1. 建议至少iphone5s以上,因为从5s开始支持arm64架构
    2. 或者至少是ipad Air、ipad mini2等支持arm64架构的设备
  • iOS9.1完美越狱
  1. 建议至少iOS8完美越狱
  2. 版本也不能太高,要保证能够完美越狱
  3. 检查手机是否可以越狱: jailbreak.25pp.com/ios

iOS Jailbreak(iOS越狱)

  • 利用iOS系统的漏洞,获取iOS系统的最高权限(Root),解开之前的各种限制(合法行为)

优点

  • 打造个性化,与众不同的iPhone
    1. 自由安装各种实用的插件、主题、APP
    2. 修改系统App的一些默认行为
  • 自由安装非AppStore来源的APP
    1. 付费app秒变免费app
  • 灵活管理文件系统,让iphone可以像U盘一样灵活
  • 给开发者提供了逆向工程的环境

缺点

  • 不予保修
  • 费电,越狱后的系统会常驻一些进程,耗电速度提升约10%~20%
  • 在新的iOS固件版本出来的时候,不能及时的进行更新
    1. 每个新版本的固件,都会修复上一个版本的越狱漏洞,使越狱失效
    2. 如果需要保持越狱状态,要等待新的越狱程序发布时,才能升级相应的固件版本
  • 不再受iOS系统默认的安全保护,容易被恶意软件攻击,个人隐私有被窃取的风险
  • 如果安装了不稳定的插件,容易让系统变得不稳定、变慢、甚至出现“白苹果”等问题

完美越狱和不完美越狱

  • 完美越狱:越狱后的iPhone可以正常关机和重启
  • 不完美越狱
    1. iPhone一旦关机后再开机时,屏幕就会一直停留在启动画面,也就是”白苹果“状态
    2. 或者能正常开机,但已经安装的破解软件都无法正常使用,需要将设备与pc连接后,使用软件进行引导才能使用
  • 一般来说,在苹果发布新的iOS固件后,针对该固件的不完美越狱会先发布,随后完美越狱才可能发布
    1. 一般新的系统版本,都是不完美越狱
  • 越狱方法推荐
    1. pp助手:jailbreak.25pp.com/

如何判断是否越狱成功

  • 桌面是否有Cydia程序
  • 工具判断(如pp助手)- 是否越狱:是

Cydia

  • 越狱之后的"App Store"
    1. 可以在Cydia中安装各种第三方的软件(插件、补丁、App)
  • 作者:Jay Freeman(saurik)

Cydia安装软件的步骤

  • 添加软件源(不同软件的软件源可能不同) 软件源-编辑-添加-添加源
  • 进入软件源找到对应的软件,开始安装

SpringBoard

  • 有的时候通过Cydia安装完插件后,可能会出现 ”重启SpringBoard“界面
  • SpringBoard就是iOS的桌面

需要安装的补丁

Apple File Conduit "2"

  • 需要安装下这个补丁,作用是
    1. 可以访问整个iOS设备的文件系统
    2. 类似的补丁还有:afc2 、 afc2add
  • 软件源:
    1. apt.saurik.com
    2. apt.25pp.com

AppSync Unified

  • 可以绕过系统验证,随意安装、运行破解的ipa安装包
  • 软件源:apt.25pp.com/

iFile

PP助手

  • 可以利用pp助手自由安装海量app
  • 软件源: apt.25pp.com/

Mac上需要安装的

  • iFunBox :管理文件系统
  • PP助手:自由安装海量app,卸载app,备份app为ipa安装包(ios9开始不再支持备份app)

建议安装顺序

iPhone:Cydia->{ Apple File Conduit"2"、AppSync Unified}-{iFile、PP助手} Mac:{iFunBox、PP助手}

安装包

  • 通常情况下
    1. 通过Cydia安装的安装包是deb格式的(结合软件包管理工具apt)
    2. 通过pp助手安装的安装包是ipa格式的
  • 如果通过Cydia源安装deb失败
    1. 可以先从网上下载deb格式的安装包:浏览器输入xxx deb
    2. 然后打开iFunBox-文件系统,软件将deb安装包放到/var/root/media/Cydia/AutoInstall ,然后重启手机,Cydia就会自动安装deb

如何判断是否越狱成功

  • 桌面是否有Cydia
  • 工具判断(比如PP助手)-显示已越狱
  • 代码判断,但是每个系统的情况不一样,可以自行网上搜索方法如下:
 if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"]) {
        NSLog(@"此设备已越狱");
    }else{
        NSLog(@"此设备未越狱");
    }

提高工作效率的工具

  • Alfred :便捷搜索 、工作流 (快捷键option+空格)
  • XtraFinder:增强型Finder
  • iTerm2 : 完爆Terminal的命令行工具
  • Go2Shell : 从Finder快速定位到命令行工具

Mac远程登录到iPhone

  • 我们经常在Mac的终端上,通过一些命令行来完成一些操作,iOS和Mac OS X都是基于Darwin(苹果的一个基于Unix的开源系统内核),所以iOS中同样支持终端的命令行操作
  • 在逆向工程中,经常通过命令行来操纵iPhone,为了能够让Mac终端中的命令行能作用在iPhone上,我们得让Mac和iPhone建立连接,通过Mac远程登录到iPhone的方式建立连接

SSH、OpenSSH

  • SSH:Secure Shell的缩写,意为“安全外壳协议“,是一种可以为远程登录提供安全保障的协议 可以阻断sniffer(嗅探器,抓数据包软件)的拦截与篡改 -使用SSH,可以把所有传输的数据进行加密,”中间人“攻击方式就不可能实现,能防止DNS欺骗和IP欺骗
  • OpenSSH:是SSH协议的免费开源实现,可以通过OpenSSH的方式让Mac远程登录到iPhone

使用OpenSSH远程登录

  • 在iPhone上通过Cydia安装OphoneSSH工具(软件源http://apt.saurik.com)
  • OpenSSH的具体使用步骤可以查看Description中的描述

使用OpenSSH远程登录- 使用步骤

  • SSH是通过TCP协议通信,所以要确保Mac和iPhone在同一局域网下,比如连接着同一个WiFi
  • 命令行:ssh root@手机ip地址(ssh 账户名@服务器主机地址) , 密码:OpenSSH的Descripthon描述里面去找默认密码(alpine); 验证是否登录上手机: 1、cd/ 2、ls -l
  • 退出登录:exit

root、mobile

  • iOS下有2个常用账户:root、mobile
  • root:最高权限账户
  • mobile: 普通权限账户,只能操作一些普通文件,不能操作系统级别的文件(登录:ssh mobile@iphone连接网络的ip地址 ,默认密码也是alpine) (ps:命令行根路径后面如果是#号,代表最高权限用户,如果是$,代表普通用户权限)
  • 最好修改一下root和mobile用户的登录密码(登录root账户后,分别通过passwd、passwd mobile完成)
    1. 登录root账户,命令行输入 passwd :修改最高权限用户的密码, 命令行输入 passwd mobile :修改mobile用户的密码 (exit:退出)

SSL、OpenSSL

  • SSL: Secure Sockets Layer的缩写,是为网络通信提供安全及数据完整性的一种安全协议,在传输层对网络连接进行加密
  • OpenSSL:SSL的开源实现,绝大部分HTTPS请求等价于:HTTP+OpenSSL。
  • OpenSSH的加密就是通过OpenSSL完成的(OpenSSH的加密依赖于OpenSSL)

SSH的版本

  • SSH协议一共2个版本(SSH-1、SSH-2),现在用的比较多的是SSH-2,客户端和服务端版本要保持一致才能通信(这里客户端代表mac,服务端代表iphone)
  • 查看SSH版本(查看配置文件的Protocol字段)
  1. mac上查看版本:命令行
    1. cd /etc/ssh
    2. ls -l
    3. cat ssh_config 寻找Protocol字段后面跟的数字
  2. iphone上查看版本:命令行
    1. 登录iphone:root@iphone网络的ip地址
    2. cd/etc/ssh
    3. ls -l
    4. cat sshd_config

客户端:/etc/ssh/ssh_config

服务端:/etc/ssh/sshd_config

SSH的通信过程

  • SSH的通信过程可以分为3大主要阶段
  1. 建立安全连接
  2. 客户端认证
  3. 数据传输

建立安全连接

  • 在建立安全连接过程中,服务器会提供自己的身份证明

01
如果客户端并无服务器端的公钥信息,就会询问是否连接到此服务器

服务器身份信息变更

  • 在建立安全连接过程中,可能会遇到以下错误信息:提醒服务器的身份信息发生了变更,依然想要连接的话按以下方法操作:
  1. vim known_hosts
  2. (dd:vim指令删除)删掉第9行,保存退出
  3. 重新输入登录服务器指令

或者直接打开known_hosts文件删除(更新)服务器的公钥信息就行 输入:ssh-keygen -R 服务器的ip地址

SSH的客户端认证方式

  • SSH-2提供了2种常用的客户端认证方式
  1. 基于密码的客户端认证(使用账号和密码即可认证)
  2. 基于秘钥的客户端认证(免密码认证,最安全的一种认证方式)
  • SSH-2默认会优先尝试“秘钥认证”,如果认证失败,才会尝试“密码认证”

SSH-基于秘钥的客户端认证

02
具体操作如下:

  1. ssh-keygen 一路回车 (客户端生成公私钥)
  2. cd ~/.ssh
  3. ls -l
  4. ssh-copy-id root@手机ip地址(将公钥追加到xxx尾部))
  5. 尝试登录root用户看看,不再需要输入密码(clear指令可以清除命令行)
  6. 可以通过指令查看授权文件:cat ~/.ssh/authorized_keys 与 cat id_rsa.pub 对比下 (authorized_keys 授权文件一开始是不存在的,自动生成的)
  • 在客户端生成一对相关联的秘钥(Key Pair):一个公钥(Public Key),一个私钥(Private Key) ssh-keygen
  1. 一路敲回车键(Enter)即可
  2. OpenSSH默认生成的是RSA秘钥,可以通过-t参数指定秘钥类型
  3. 生成的公钥:~/.ssh/id_rsa.pub
  4. 生成的秘钥:~/ssh/id_rsa
  • 把客户端的公钥内容追加到服务器的授权文件(~/.ssh/authorized_keys)尾部 ssh-copy-id root@服务器主机地址
  1. 需要输入root用户的登录密码
  2. ssh-copy-id会将客户端~/.ssh/id_rsa.pud的内容自动追加到服务器的~/.ssh/authorized_keys尾部
  • 注意:由于是在~文件夹下操作,所以上述操作仅仅是解决了root用户的登录问题(不会影响mobile用户)

公钥 >> 授权文件

  • 可以使用ssh-copy-id将客户端的公钥内容自动追加到服务器的授权文件尾部,也可以手动操作。复制客户端的公钥到服务器某路径
  1. scp ~/.ssh/id_rsa.pud root@服务器主机地址:~
  2. scp是secure copy的缩写,是基于SSH登录进行安全的远程文件拷贝命令,把一个文件copy到远程另外一台主机上
  • 命令行如下:
  1. ssh root@服务器ip地址
  2. cd .ssh
  3. ls -l
  4. rm authorized_keys
  5. exit (先删除之前已经创建过的授权文件)
  6. cd .ssh
  7. ls -l
  8. scp ~/.ssh/id_rsa.pud root@服务器ip地址:~/.ssh(从客户端拷贝公钥到服务端)
  9. ssh root@服务器ip地址
  10. cd .ssh
  11. ls -l
  12. cat id_rsa.pud >> authorized_keys(将id_rsa.pub追加到authorized_keys尾部,如果不存在authorized_keys文件,也可以相当于重新创建这个文件)
  13. rm id_rsa.pub
  14. chmod 755 ~(如果配置了免密码登录后,还是还要一直输入密码的话,赋予服务端文件权限)
  15. chmod 755 ~/.ssh
  16. chmod 644 ~/.ssh/authorized.keys

22端口

  • 端口就是设备对外提供服务的窗口,每个端口都有个端口号(范围是0~65535,共2^16个)
  • 有些端口号是保留的,已经规定了用途,比如
  1. 21端口提供FTP服务
  2. 80端口提供HTTP服务
  3. 32端口SSH服务(可以查看/etc/ssh/sshd_config的Port字段)
  4. 更多保留端口号:百度吧
  • iPhone默认是使用22端口进行SSH通信,采用的TCP协议(mac是通过wifi(SSH登录)登录到iPhone的22端口的)

通过USB进行SSH登录

  • 默认情况下,由于SSH走的是TCP协议,Mac是通过网络连接的方式SSH登录到iPhone,要求iPhone连接WiFi
  • 为了加快传输速度,也可以通过USB连接的方式进行SSH登录(Mac上有个服务程序usbmuxd,它会开机自动启动,可以将Mac的数据通过USB传输到iPhone) (usbmuxd的路径:/System/Library/PrivateFrameworks/MobileDevice.framework/Resources/usbmuxd)

3

usbmuxd的使用1

  • 下载usbmuxd工具包(下载v1.0.8版本,主要用到里面的一个python脚本:tcprelay.py) cgit.sukimashita.com/usbmuxd.git… 下载下来后只留下两个.py文件,其他的都没啥用给删掉吧
  • 将iPhone的22端口(SSH端口)映射到Mac本地的10010端口
  1. cd ~/Documents/usbmuxd-1.0.8/python-client
  2. python tcprelay.py -t 22:10010 加上-t参数是为了能够同时支持多个SSH连接
  • 注意:要想保持端口映射状态,不能终止此命令行(如果要执行其他终命令行,请新开一个终端界面)

04

  • 不一定非要10010端口,只要不是保留端口就行

usbmuxd的使用2

  • 端口映射完毕后,以后如果想跟iPhone的22端口通信,直接跟Mac本地的10010端口通信就可以了 新开一个终端界面,SSH登录到Mac本地的10010端口(以下方式2选1) 命令行:
  1. ssh root@localhost -p 10010
  2. ssh root@127.0.0.1 -p 10010 (本地虚拟网卡的IP地址) localhost是一个域名,指向的IP地址是127.0.0.1,本机虚拟网卡的IP地址
  • usbmuxd会将Mac本地10010端口的TCP协议数据,通过USB连接转发到iPhone的22端口
  • 拷贝公钥文件到本地的10010端口(ps:没啥用练习操作下,其实只是增加了一种连接方式,这些拷贝文件的操作都不需要,因为已经操作过了 ,都还存在呢)
  1. scp -P 10010 ~/.ssh/id_rsa.pub root@loaclhost:~
  2. ssh -p 10010 root@localhost(登录本地的10010端口)
  3. ls -l
  4. rm id_rsa.pub

sh脚本文件

  • 我们可以将经常执行的一系列终端命令行放到sh脚本文件中(shell),然后执行脚本文件
  1. 打开路径
  2. vim usb.sh
  3. 按i进入编辑模式,复制(python ~/Documents/iOS/usbmuxd/tcprelay.py -t 22:10010)进去,保存退出
  4. cat usb.sh 查看usb.sh文件
  5. sh usb.sh
  6. control+c退出命令行11
  • 可以通过sh、bash、source命令来执行sh脚本文件
  1. sh、bash:当前shell环境会启动一个子进程来执行脚本文件,执行后返回到父进程的shell环境。执行cd时,在子进程中会进入到cd的目录,但是在父进程中环境并没有改变,也就是说目录没有改变
  2. source:在当前的shell环境下执行脚本文件,执行cd后会跳转到cd的目录,source可以用一个点“."来替代,比如“. test.sh" ps:还可以做一个login.sh

iOS终端的中文乱码问题

  • 默认情况下,iOS终端不支持中文输入和显示
  • 解决方案:新建一个~/.inputrc文件,文件内容是:
  1. 不将中文字符转化为转义序列,set convert-meta off
  2. 允许向终端输出中文,set output-meta on
  3. 允许向终端输入中文,set meta-flag on, set input-meta on
  • 如果想在终端编辑文件内容,可以通过Cydia安装一个vim(软件源http://apt.saurik.com)

  • 终端操作如下: ps:先让手机支持vim,下载安装软件源后操作

  1. vim .inputrc
  2. 将以下内容拷贝进去: set convert-meta off set output-meta on set meta-flag on set input-meta on
  3. 这时候登录到手机端,就可以支持中文啦

Cycript

  • Cycript是Objective-C++、ES6(JavaScript)、Java等语法的混合物
  • 可以用来探索、修改、调试正在运行的Mac\iOS APP
  • 官网:www.cycript.org/
  • 文档:www.cycript.org/manual/
  • 通过Cydia安装Cycript,即可在iPhone上调试运行中的APP

ps命令

  • 安装adv-cmds
  • ps命令是process status的缩写,使用ps命令可以列出系统当前的进程
  1. 列出所有的进程(ps -A)
  2. 搜索关键词(ps -A | grep 关键词)

Cycript的开启和关闭

操作步骤

  1. 先登录上iPhone
  2. ps -A
  3. cycript -p 7661 或者 cycript -p neteasemusic 网易云音乐为例 ( cycript (开启)) control+d(退出) cycript -p 进程ID/进程名称 )

常用语法1

  • UIApp : 等价于[UIApplication sharedApplication]
  • 定义变量:var 变量名 = 变量值
  1. 列:var app = UIApp.keyWindow
  • 用内存地址获取对象(命令为:#内存地址)
  • ObjectiveC.classes ( 该app已加载的所有OC类 )
  • 查看对象的所有成员变量(指令: *UIApp 或者 *#内存地址)
  • 递归打印view的所有子控件(跟LLDB一样的函数:po [self.view.window recursiveDescription] 打印所有的子控件) 列:UIApp.keyWindow.recursiveDescription().toString()

常用语法2

  • 筛选出某种类型的对象 choose(UIViewController) choose(UITableViewCell) (如果奔溃的话,要重新进入该进程然后继续操作)

动态调试网易云

列:

  1. 先连接到服务器,scp -P 10010 ~/Documents/iOS/LFTool.js root@localhost:/usr/lib/cycript0.9/LFTool.cy (将LFTool.js拷贝到LFTool.cy文件中)
  2. cycript -p neteasemusic(网易云音乐)
  3. @import LFTool (导入库)
  4. LFTopVc() (该方法可以拿到当前显示的最上层VC ,封装好的哦~)
  5. LFInstanceMethodNames(#控制器内存地址) (打印该控制器所有对象方法)
  6. [#控制器内存地址 loginButtonClicked:nil] (点击登录按钮)
  7. LFSubviews(#控制器内存地址.view) (打印所有的子view)
  8. #textfiled的内存地址.text = "777" (篡改内容)
  9. LFClassMethodNames(#控制器内存地址) (打印改控制器中所有的类方法) control+c:全部删掉
  10. LFInstanceMethodNames(#控制器内存地址) (对象方法)
  • 列,找到button的view,并且删掉该button 思路:通过“登录”两字确定view
  1. python (进入python环境,查看“登录”的unicode编码)
  2. unicode('登录‘,'UTF-8’)
  3. [#登录按钮内存地址 removeFromSuperview] 删掉登录按钮
  4. LFAppId
  5. var view = [[UIView alloc] init]
  6. view.frame = MJRectMake(0,0,100,100)
  7. view.backgorundColor = [UIColor redColor]
  • 也可以使用正则 LFInstanceMethodNames(#控制器内存地址, /login/)、 LFInstanceMethodNames(#控制器内存地址, /View$/) 以View结尾的

附:LFTool.cy文件

作者简介

就职于甜橙金融 ( 翼支付 ) 信息技术部,负责iOS客户端开发