文档价值
- 掌握编码的本质,编写高效代码
- 修改已有App的功能
- 学习优秀App的设计
- 增强客户端的安全性
- 通用性极强(越底层,通用性越强)
越狱环境搭建
知识储备
- UI界面
- 多线程
- 数据存储
设备
- 调试设备 iphone
- 建议至少iphone5s以上,因为从5s开始支持arm64架构
- 或者至少是ipad Air、ipad mini2等支持arm64架构的设备
- iOS9.1完美越狱
- 建议至少iOS8完美越狱
- 版本也不能太高,要保证能够完美越狱
- 检查手机是否可以越狱: jailbreak.25pp.com/ios
iOS Jailbreak(iOS越狱)
- 利用iOS系统的漏洞,获取iOS系统的最高权限(Root),解开之前的各种限制(合法行为)
优点
- 打造个性化,与众不同的iPhone
- 自由安装各种实用的插件、主题、APP
- 修改系统App的一些默认行为
- 自由安装非AppStore来源的APP
- 付费app秒变免费app
- 灵活管理文件系统,让iphone可以像U盘一样灵活
- 给开发者提供了逆向工程的环境
缺点
- 不予保修
- 费电,越狱后的系统会常驻一些进程,耗电速度提升约10%~20%
- 在新的iOS固件版本出来的时候,不能及时的进行更新
- 每个新版本的固件,都会修复上一个版本的越狱漏洞,使越狱失效
- 如果需要保持越狱状态,要等待新的越狱程序发布时,才能升级相应的固件版本
- 不再受iOS系统默认的安全保护,容易被恶意软件攻击,个人隐私有被窃取的风险
- 如果安装了不稳定的插件,容易让系统变得不稳定、变慢、甚至出现“白苹果”等问题
完美越狱和不完美越狱
- 完美越狱:越狱后的iPhone可以正常关机和重启
- 不完美越狱
- iPhone一旦关机后再开机时,屏幕就会一直停留在启动画面,也就是”白苹果“状态
- 或者能正常开机,但已经安装的破解软件都无法正常使用,需要将设备与pc连接后,使用软件进行引导才能使用
- 一般来说,在苹果发布新的iOS固件后,针对该固件的不完美越狱会先发布,随后完美越狱才可能发布
- 一般新的系统版本,都是不完美越狱
- 越狱方法推荐
- pp助手:jailbreak.25pp.com/
如何判断是否越狱成功
- 桌面是否有Cydia程序
- 工具判断(如pp助手)- 是否越狱:是
Cydia
- 越狱之后的"App Store"
- 可以在Cydia中安装各种第三方的软件(插件、补丁、App)
- 作者:Jay Freeman(saurik)
Cydia安装软件的步骤
- 添加软件源(不同软件的软件源可能不同) 软件源-编辑-添加-添加源
- 进入软件源找到对应的软件,开始安装
SpringBoard
- 有的时候通过Cydia安装完插件后,可能会出现 ”重启SpringBoard“界面
- SpringBoard就是iOS的桌面
需要安装的补丁
Apple File Conduit "2"
- 需要安装下这个补丁,作用是
- 可以访问整个iOS设备的文件系统
- 类似的补丁还有:afc2 、 afc2add
- 软件源:
AppSync Unified
- 可以绕过系统验证,随意安装、运行破解的ipa安装包
- 软件源:apt.25pp.com/
iFile
- 可以在iPhone上自由访问iOS文件系统
- 类似的还有Filza File Mnaager、File Browser
- 软件源(BigBoss):apt.thebigboss.org/repofiles/c…
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助手}
安装包
- 通常情况下
- 通过Cydia安装的安装包是deb格式的(结合软件包管理工具apt)
- 通过pp助手安装的安装包是ipa格式的
- 如果通过Cydia源安装deb失败
- 可以先从网上下载deb格式的安装包:浏览器输入xxx deb
- 然后打开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完成)
- 登录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字段)
- mac上查看版本:命令行
- cd /etc/ssh
- ls -l
- cat ssh_config 寻找Protocol字段后面跟的数字
- iphone上查看版本:命令行
- 登录iphone:root@iphone网络的ip地址
- cd/etc/ssh
- ls -l
- cat sshd_config
客户端:/etc/ssh/ssh_config
服务端:/etc/ssh/sshd_config
SSH的通信过程
- SSH的通信过程可以分为3大主要阶段
- 建立安全连接
- 客户端认证
- 数据传输
建立安全连接
- 在建立安全连接过程中,服务器会提供自己的身份证明
服务器身份信息变更
- 在建立安全连接过程中,可能会遇到以下错误信息:提醒服务器的身份信息发生了变更,依然想要连接的话按以下方法操作:
- vim known_hosts
- (dd:vim指令删除)删掉第9行,保存退出
- 重新输入登录服务器指令
或者直接打开known_hosts文件删除(更新)服务器的公钥信息就行 输入:ssh-keygen -R 服务器的ip地址
SSH的客户端认证方式
- SSH-2提供了2种常用的客户端认证方式
- 基于密码的客户端认证(使用账号和密码即可认证)
- 基于秘钥的客户端认证(免密码认证,最安全的一种认证方式)
- SSH-2默认会优先尝试“秘钥认证”,如果认证失败,才会尝试“密码认证”
SSH-基于秘钥的客户端认证
- ssh-keygen 一路回车 (客户端生成公私钥)
- cd ~/.ssh
- ls -l
- ssh-copy-id root@手机ip地址(将公钥追加到xxx尾部))
- 尝试登录root用户看看,不再需要输入密码(clear指令可以清除命令行)
- 可以通过指令查看授权文件:cat ~/.ssh/authorized_keys 与 cat id_rsa.pub 对比下 (authorized_keys 授权文件一开始是不存在的,自动生成的)
- 在客户端生成一对相关联的秘钥(Key Pair):一个公钥(Public Key),一个私钥(Private Key) ssh-keygen
- 一路敲回车键(Enter)即可
- OpenSSH默认生成的是RSA秘钥,可以通过-t参数指定秘钥类型
- 生成的公钥:~/.ssh/id_rsa.pub
- 生成的秘钥:~/ssh/id_rsa
- 把客户端的公钥内容追加到服务器的授权文件(~/.ssh/authorized_keys)尾部 ssh-copy-id root@服务器主机地址
- 需要输入root用户的登录密码
- ssh-copy-id会将客户端~/.ssh/id_rsa.pud的内容自动追加到服务器的~/.ssh/authorized_keys尾部
- 注意:由于是在~文件夹下操作,所以上述操作仅仅是解决了root用户的登录问题(不会影响mobile用户)
公钥 >> 授权文件
- 可以使用ssh-copy-id将客户端的公钥内容自动追加到服务器的授权文件尾部,也可以手动操作。复制客户端的公钥到服务器某路径
- scp ~/.ssh/id_rsa.pud root@服务器主机地址:~
- scp是secure copy的缩写,是基于SSH登录进行安全的远程文件拷贝命令,把一个文件copy到远程另外一台主机上
- 命令行如下:
- ssh root@服务器ip地址
- cd .ssh
- ls -l
- rm authorized_keys
- exit (先删除之前已经创建过的授权文件)
- cd .ssh
- ls -l
- scp ~/.ssh/id_rsa.pud root@服务器ip地址:~/.ssh(从客户端拷贝公钥到服务端)
- ssh root@服务器ip地址
- cd .ssh
- ls -l
- cat id_rsa.pud >> authorized_keys(将id_rsa.pub追加到authorized_keys尾部,如果不存在authorized_keys文件,也可以相当于重新创建这个文件)
- rm id_rsa.pub
- chmod 755 ~(如果配置了免密码登录后,还是还要一直输入密码的话,赋予服务端文件权限)
- chmod 755 ~/.ssh
- chmod 644 ~/.ssh/authorized.keys
22端口
- 端口就是设备对外提供服务的窗口,每个端口都有个端口号(范围是0~65535,共2^16个)
- 有些端口号是保留的,已经规定了用途,比如
- 21端口提供FTP服务
- 80端口提供HTTP服务
- 32端口SSH服务(可以查看/etc/ssh/sshd_config的Port字段)
- 更多保留端口号:百度吧
- 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)
usbmuxd的使用1
- 下载usbmuxd工具包(下载v1.0.8版本,主要用到里面的一个python脚本:tcprelay.py) cgit.sukimashita.com/usbmuxd.git… 下载下来后只留下两个.py文件,其他的都没啥用给删掉吧
- 将iPhone的22端口(SSH端口)映射到Mac本地的10010端口
- cd ~/Documents/usbmuxd-1.0.8/python-client
- python tcprelay.py -t 22:10010 加上-t参数是为了能够同时支持多个SSH连接
- 注意:要想保持端口映射状态,不能终止此命令行(如果要执行其他终命令行,请新开一个终端界面)
- 不一定非要10010端口,只要不是保留端口就行
usbmuxd的使用2
- 端口映射完毕后,以后如果想跟iPhone的22端口通信,直接跟Mac本地的10010端口通信就可以了 新开一个终端界面,SSH登录到Mac本地的10010端口(以下方式2选1) 命令行:
- ssh root@localhost -p 10010
- 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:没啥用练习操作下,其实只是增加了一种连接方式,这些拷贝文件的操作都不需要,因为已经操作过了 ,都还存在呢)
- scp -P 10010 ~/.ssh/id_rsa.pub root@loaclhost:~
- ssh -p 10010 root@localhost(登录本地的10010端口)
- ls -l
- rm id_rsa.pub
sh脚本文件
- 我们可以将经常执行的一系列终端命令行放到sh脚本文件中(shell),然后执行脚本文件
- 打开路径
- vim usb.sh
- 按i进入编辑模式,复制(python ~/Documents/iOS/usbmuxd/tcprelay.py -t 22:10010)进去,保存退出
- cat usb.sh 查看usb.sh文件
- sh usb.sh
- control+c退出命令行11
- 可以通过sh、bash、source命令来执行sh脚本文件
- sh、bash:当前shell环境会启动一个子进程来执行脚本文件,执行后返回到父进程的shell环境。执行cd时,在子进程中会进入到cd的目录,但是在父进程中环境并没有改变,也就是说目录没有改变
- source:在当前的shell环境下执行脚本文件,执行cd后会跳转到cd的目录,source可以用一个点“."来替代,比如“. test.sh" ps:还可以做一个login.sh
iOS终端的中文乱码问题
- 默认情况下,iOS终端不支持中文输入和显示
- 解决方案:新建一个~/.inputrc文件,文件内容是:
- 不将中文字符转化为转义序列,set convert-meta off
- 允许向终端输出中文,set output-meta on
- 允许向终端输入中文,set meta-flag on, set input-meta on
-
如果想在终端编辑文件内容,可以通过Cydia安装一个vim(软件源http://apt.saurik.com)
-
终端操作如下: ps:先让手机支持vim,下载安装软件源后操作
- vim .inputrc
- 将以下内容拷贝进去: set convert-meta off set output-meta on set meta-flag on set input-meta on
- 这时候登录到手机端,就可以支持中文啦
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命令可以列出系统当前的进程
- 列出所有的进程(ps -A)
- 搜索关键词(ps -A | grep 关键词)
Cycript的开启和关闭
操作步骤
- 先登录上iPhone
- ps -A
- cycript -p 7661 或者 cycript -p neteasemusic 网易云音乐为例 ( cycript (开启)) control+d(退出) cycript -p 进程ID/进程名称 )
常用语法1
- UIApp : 等价于[UIApplication sharedApplication]
- 定义变量:var 变量名 = 变量值
- 列: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) (如果奔溃的话,要重新进入该进程然后继续操作)
动态调试网易云
列:
- 先连接到服务器,scp -P 10010 ~/Documents/iOS/LFTool.js root@localhost:/usr/lib/cycript0.9/LFTool.cy (将LFTool.js拷贝到LFTool.cy文件中)
- cycript -p neteasemusic(网易云音乐)
- @import LFTool (导入库)
- LFTopVc() (该方法可以拿到当前显示的最上层VC ,封装好的哦~)
- LFInstanceMethodNames(#控制器内存地址) (打印该控制器所有对象方法)
- [#控制器内存地址 loginButtonClicked:nil] (点击登录按钮)
- LFSubviews(#控制器内存地址.view) (打印所有的子view)
- #textfiled的内存地址.text = "777" (篡改内容)
- LFClassMethodNames(#控制器内存地址) (打印改控制器中所有的类方法) control+c:全部删掉
- LFInstanceMethodNames(#控制器内存地址) (对象方法)
- 列,找到button的view,并且删掉该button 思路:通过“登录”两字确定view
- python (进入python环境,查看“登录”的unicode编码)
- unicode('登录‘,'UTF-8’)
- [#登录按钮内存地址 removeFromSuperview] 删掉登录按钮
- LFAppId
- var view = [[UIView alloc] init]
- view.frame = MJRectMake(0,0,100,100)
- view.backgorundColor = [UIColor redColor]
- 也可以使用正则 LFInstanceMethodNames(#控制器内存地址, /login/)、 LFInstanceMethodNames(#控制器内存地址, /View$/) 以View结尾的
作者简介
就职于甜橙金融 ( 翼支付 ) 信息技术部,负责iOS客户端开发