前言:
玩逆向的目的 ?
- 为了应用安全 , 我们首先要知道
Hackers
都是怎么做的 , 他们如何做到可以调试我们的应用 . 在此基础上我们才能知道如何更有效的进行防护.在逆向的路上 , 很重要的一步就是应用重签名 , 以此达到调试别人应用的目的.
想知道如何重签名 , 首先要知道
iOS
应用签名的原理 .
提示 :
本篇文章建立在对加密和签名有一定了解的基础上 . 如不太熟悉建议阅读前一篇博客 RSA加密原理&密码学&HASH 或者其他密码学以及签名文章.
废话不多说 , 开始.
iOS 应用签名原理
签名
为什么用签名这个词 . 因为老外喜欢用支票 , 支票上面的签名能够证明这玩意是你的 . 那么数字签名顾名思义 , 就是用于鉴别数字信息的方法
代码签名
代码签名是对可执行文件或脚本进行数字签名 . 用来确认软件是被认可的 , 且在签名后未被修改或损坏的措施。和数字签名原理一样 , 只不过签名的数据是代码而已.
其具体验证措施如下 :
发布者
将源代码散列后的 HASH
值使用私钥进行加密然后和源代码一起产生一个软件包 . 那么 验证端/使用端
收到后使用公钥解密拿到 HASH
, 并使用 HASH
算法对源代码进行散列 , 将得到的结果进行比对 , 如果一致 , 则说明数据没有被篡改过 , 并且确实是由发布者发布的应用 .
苹果的应用安装需求
在 iOS 出来之前 , 以前的主流操作系统( Mac/Windows
) 软件随便从哪里下载都能运行 , 系统安全存在隐患 , 盗版软件 , 病毒入侵 , 静默安装等等 . 那么苹果希望解决这样的问题,要保证每一个安装到 iOS 上的 APP
都是经过苹果官方允许的,怎样保证呢 ? 就是通过代码签名。
那么首先怎么实现呢 ?
- 苹果服务器有一个私钥 , 每台设备上有一个公钥 . 以此来保证每个安装的应用都是经过苹果服务器的允许的 .
这样确实可以保证 , 但是我们还有开发者 , 需要通过 Xcode
在开发阶段就能安装应用 , 另外还有企业证书 . 所以 实际上 , 苹果的签名机制是双层签名.
iOS 应用签名流程
整个完整流程如上图 , 接下来我们结合实际操作来剖析一下其原理 .
1. 开发时期 , 申请证书
在我们希望安装开发好的程序到 iPhone
上时 , 我们都知道需要去开发者中心配置一下证书 .
MAC
通过钥匙串访问生成请求CSR
文件.
这一步骤其实就是MAC
生成了一对 公私钥M , 将公钥M
放到请求文件CSR
中上传给苹果服务器 .苹果服务器利用 私钥A 对
公钥M
进行数字签名 ( 其实就是对公钥M
值进行非对称加密 , 然后保存了公钥M
的HASH
值 ) , 生成的结果就是 证书 .然后用户继续添加设备
UDID
, 选择证书 , 配置所需权限 . 生成描述文件 .当用户下载下来 /
Xcode
自动管理把证书下载下来之后 , 钥匙串访问就会将证书和MAC
中的私钥M
( 就是我们所熟知的p12
) 进行关联 .
2. 编译安装
Xcode
在我们选择好了描述文件和开发者账户进行编译时 :
首先 ,
Xcode
会利用证书锁所关联的私钥M
, 对APP
进行代码签名 ( 将源文件的HASH
值通过私钥M
进行加密 ) . 然后会把描述文件和签名 以及可执行文件MachO
一起打包 .-
当这个步骤完成 .
iPhone
手机要对该软件包进行校验 .- 首先 , 苹果根据
iOS
系统中的 私钥A 对描述文件中的证书进行解密校验 . 通过则意味着这个证书是苹果颁发的 , 也就是说是被许可的 . - 当第一步完成解密 , 就拿到了
公钥M
, 然后进行HASH
校验是否被篡改过 . - 拿到
公钥M
之后 , 使用公钥M
去验证APP
的签名 , 以此来验证 这个证书是不是这个APP
的. ( 这也就是为什么别的小伙伴生成的证书需要把p12
发给其他人来真机调试的原因 . ) - 然后校验
UDID
等等.
- 首先 , 苹果根据
这就是 iOS 应用完整的双层签名流程了. 讲完签名原理 , 不急着研究重签名 , 先打下点基础知识 , 来看看描述文件 .
描述文件
那么我们来看一下描述文件到底是个啥东西.
打开目录
/Users/**你的名字**/Library/MobileDevice/Provisioning Profiles
随便选择一个 , 使用终端查看
security cms -Di 0b7f1352-7a1e-4800-b52b-f2fc35e550dd.mobileprovision
往下找到一个 entitlements
的 key
和其 value
.
<key>Entitlements</key>
<dict>
<key>aps-environment</key>
<string>development</string>
<key>application-identifier</key>
<string>4NJV3PZG3A.com.libin.WMXJ</string>
<key>keychain-access-groups</key>
<array>
<string>4NJV3PZG3A.*</string>
</array>
<key>get-task-allow</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>4NJV3PZG3A</string>
</dict>
这个 entitlements
就是权力配置 , 在重签名中会使用到. 描述文件中还包含了所有 APP
的配置内容 , 大家有兴趣可以一一查看.
那么 , 苹果是如何签名的我们知道了 . 那问题来了 , 如何去做重签名 ?
iOS 应用重签名
其实 iOS 应用签名部分都是利用了 CodeSign
来完成的 . 我们可以利用终端来自己进行签名 .
目前市面上也有许多应用可以可视化完成重签 或者一键重签 . 或者利用写好的 shell
脚本来玩 . 对于初学者 . 个人建议还是按照最基础的方式操作几遍 , 理解了其原理 , 在使用其他工具碰到为题也比较好处理 , 当然 , 本篇文章会介绍如何手写 shell 来完成重签名.
准备工具 / 包
pp助手
pp助手 for Mac : 用来下载砸完壳的应用.
下载完成打开 ,被阻拦非 App Stroe
下载的应用打开的解决办法就不再介绍了. 设置 - 安全性与隐私 / 或者使用终端都可以 .
找到越狱应用下载微信
下载 ipa
完成 , 重命名为 zip
, 解压缩 找到 Payload
- WeChat
.
查看文件
应用签名
弄了半天 , 我们先来看看这个东西 .
Iterm2
/ 终端命令:
codesign -vv -d WeChat.app
其中有一项 : Authority
, 就是应用签名 .
那么我们现在要用我们自己的证书 去重新签名 .
MachO 文件
在 WeChat
文件显示包内容 , 找到一个黑框框 WeChat
文件.
这个就是我们经常提到的 MachO
文件了 . 后续我会专门讲解它 以及如何仔细查看.
现在我们先来简单查看一下 , 利用 otool
工具.
命令 : otool -l WeChat
.
内容比较多 , 我们重定向一下 , 写到一个文件里.
命令 : otool -l WeChat > /Users/libin/Desktop/iOS进阶逻辑课程/逆向/WeChatMaCho.txt
( 名称和路径随便 ) .
写完后我们打开文件 , 搜索 cryptid
,
注意 : cryptid
是 0
, 代表你下载的是砸过壳的 , 而一般应用是 1
, 也就是加密过的 , 其实就是 AppStore
使用的对称性加密 , iPhone
在运行的时后解密 ( 并非安装时就解密 ) .
写了这么多 , 终于要开始重签名了 . GO
-->
步骤1 : 查看自己电脑上证书
命令: security find-identity -v -p codesigning
.
选择一个 , 复制下来 .
这里我就不列举笔者自己的了.
还完全没有证书的小伙伴
iPhone
, 不要选成了 Mac
.
步骤2 : 删插件
打开
WeChat
, 显示包内容 . 找到PlugIns
文件夹, 直接删除 插件普通账号是签不了的 .找到
Watch
文件夹 , 因为这里也有插件 , 我们暂时不需要Watch
, 直接删掉.
步骤3 : 重签 FrameWork
-
进入
FrameWork
文件夹
-
利用
CodeSign
, 使用我们的证书进行重签名.codesign -fs "刚刚复制的你自己的证书名字" 要重签的FrameWork名称
- 例如:
codesign -fs "iPhone Developer: ha ha (123456)" andromeda.framework
- 把
FrameWork
文件夹下所有的库全部重签.
步骤4 : 确保 MachO 执行权限
最简单的方式就是预览框中 , 黑色就代表可执行 , 灰色就代表不可执行 .
或者 命令 : ls -l WeChat
, 结果是 -rwxr-xr-x
或者其他权限.
如果没有可执行权限 , 也就是 x
权限 , 可以通过 chmod +x WeChat
添加权限.
( 关于 Linux
权限和命令这块儿如果大家不是很清楚 , 留言一下 , 我后面补一篇文章详细讲讲 , 毕竟有些面试还是会问 , 不能只知道一个 777 , 因为很多是已经知道了 , 本文就暂不赘述了 )
步骤5 : 给包添加描述文件
因为我们下载的是上线包 , 肯定是没有描述文件这种东西在包里的 . 因此我们需要自己生成一个 .
- 打开
Xcode
, 新建工程 我这里取名WeChatDemo
. 然后选择真机 , 选择开发者 , 自动 / 手动管理都可以 , 我这里勾选自动 , 然后运行 , 把这个空工程安装到手机上.
- 打开
-
安装成功之后 , 把这个描述文件放到微信的包中.
-
步骤6 : 更改 Bundle ID
- 微信包中找到
Info.plist
- 修改
Bundle identifier
-
com.tencent.xin
改为你自己刚刚新建工程的Bundle identifier
我这里为com.libin.WeChatDemo
-
步骤7 : 通过授权文件(Entilements)重签.app包
-
利用上文中我们说的查看描述文件方法 , 查看我们刚刚拷贝到微信包里的描述文件 . 也就是我们自己空工程生成的描述文件. 找到权力文件部分
-
打开我们刚刚新建的
Xcode
工程 , 新建一个Plist
文件 ,Open As Source Code
-
把上上图中描述文件的权利文件部分复制 , 粘贴到新建的
Plist
中 ,
为了确保无误 可再次Open As Property List
查看下. 其实就是为了得到一个 plist 文件备用. 也可以用其它方式. -
新建的
Plist
写好后 ,Show In Finder
. 将其放到微信包同路径中 , 方便操作.
重点 : 重签命令 --
codesign -fs "iPhone Developer: haha (123456)" --no-strict --entitlements=ent.plist WeChat.app
(注意替换自己的证书 , 文件)
见证奇迹的时刻
cmd + shift + 2
- 点击加号 , 选择我们的微信包.
(注意这一步之前最好检查下 微信包中Bundle ID
有没有换成自己工程的 , 防止原版微信被替换了 )
注意看 , 手机上之前那个空工程变成了微信了 .
( 注意如果有安装失败的同学 , 先检查自己步骤有无错误 , 如没有 可尝试不使用 Xcode
自动生成证书以及描述文件 , 自己去开发者中心配置 , 选择.)
点击冒牌微信打开 , 微信项目启动了.
简单调试
打开附加 , 注意 , 如果你跟我一样有两个微信 , 那么哪个后开 , 哪个进程数字较大 . 因此自己判定哪个是冒牌的就好.
选择之后 注意看上方状态栏 , 变成 running
就好
然后就可以使用 view debug
/ LLDB
, 添加符号断点等等调试方法了 .
由于篇幅问题 , 本文不多赘述了 , 后面会补充 shell
脚本自动重签实现 , 直接更换包实现 , 后续会继续就代码注入 等方面展开 .