一. 重签名概述
请思考:签名是可以被替换的吗?
签名
是对原始数据的Hash值进行加密
,重签名
就是将原始数据的Hash值用当前的证书重新加密
,所以签名是可以被替换的。其中代码签名用来验证我们的app
下面我们来查看越狱包的信息?
这里准备的是越狱的包微信-7.0.8.ipa
,这个ipa包解压完成之后会有一个微信-7.0.8
文件夹。
// 进入上面解压的文件夹目录
$ cd /Users/wn/010--应用重签名原理/资料/微信-7.0.8/Payload
// 其中的WeChat.app包含两个东西:app与app签名信息
$ ls
WeChat.app
// 查看app包的签名信息
$ codesign -vv -d WeChat.app
Executable=/Users/wn//010--应用重签名原理/资料/微信-7.0.8/Payload/WeChat.app/WeChat
Identifier=com.tencent.xin
Format=app bundle with Mach-O thin (arm64)
CodeDirectory v=20400 size=972531 flags=0x0(none) hashes=30383+5 location=embedded
Signature size=4864
// 这里就是签名权限信息
Authority=iPhone Distribution: Tencent Technology (Shenzhen) Company Limited (88L2Q4487U)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=Oct 16, 2019 at 5:54:10 PM
Info.plist entries=68
TeamIdentifier=88L2Q4487U
Sealed Resources version=2 rules=10 files=1470
Internal requirements count=1 size=212
// 查看钥匙串的证书
$ security find-identity -v -p codesigning
// 查看可执行文件详细信息
$ otool -l WeChat > ~/Desktop/123.txt
其中123.txt文件内有参数cryptid表示加密id(0表示没有使用加密算法,非0表示加过密的)
这里cryptid值为0,也就是当前可执行文件没有加密,俗称砸过壳的
Xocde提供了签名工具codesign
,我们通过几个命令就可以完成重签名
列出钥匙串里可签名的证书
$security find-identity -v -p codesigning
强制替换签名
$Codesign –fs “证书串” 文件名
给文件添加权限
$Chmod +x 可执行文件
查看描述文件
$security cms -D -i ../embedded.mobileprovision
$codesign -fs “证书串” --no-strict --entitlements=权限文件.plist APP包
将输入文件压缩为输出文件
$Zip –ry 输出文件 输入文件
如何获取越狱手机的ipa包
// 先进入资料目录
$ cd /Users/wn/Documents/资料/汇编/010--应用重签名原理/资料
// 建立链接
$ sh usbConnect.sh
// 连接手机
$ sh usbX.sh
// 查看进程
$ ps -A
// 筛选进程,找到当前微信进程
$ ps -A | grep WeChat
// 拷贝,这个app包是官方的,没有砸过壳的,只有越狱过的手机才能copy
$ scp -r -P 12345 root@localhost:路径 ./
// 查看拷贝的app包
$ cd WeChat.app
// 查看可执行文件,此时的cryptid 是 1,表示加密过的
$ otool -l WeChat | grep crypt
// 查看app的权限,发现这里是一个正版的app
$ codesign -vv -d WeChat.app
注意 MachO最重要的两块:代码块
与数据块
,其中主要是加密代码块
二. CodeSign重签名
重签名步骤
- 删除插件和带有插件的.app包(比如Watch)
- 对
Frameworks
里面的库进行重签名 - 给可执行文件 +x(可执行)权限
- 添加描述文件(新建工程,真机编译得到,而且要运行,将描述文件安装到手机)
- 替换
BundleID
(info.plist 文件。 BundleID要和描述文件中的ID保持一致) - 通过授权文件(Entilements)重签.app包、
- 查看描述文件
$security cms -D -i embedded.mobileprovision
- 将描述文件中
Entilements
拷贝出来,生成plist文件。(文件名称entitlements.plist ) - 用权限文件签名APP包
$ codesign -fs "Apple Development: XX(XX)" --no-strict --entitlements=entitlements.plist WeChat.app
- 最后通过Xcode安装
准备工作
- 上面
WeChat.app
包里需要签名的内容:WeChat
可执行文件与Frameworks
动态库 - 免费普通账户无法对
WeChat.app
包里的插件进行签名,需要删除。如PlugIns
Watch
目录里面的插件,这些插件里面都有相应的可执行文件。删除上面插件对app安装没有影响
- 查看Frameworks里面动态库发现也有签名信息
$ codesign -vv -d andromeda.framework
Executable=/Users/wn/Documents/资料/微信-7.0.8/Payload/WeChat.app/Frameworks/andromeda.framework/andromeda
Identifier=com.tencent.wc.mp.andromeda-dylib
Format=bundle with Mach-O thin (arm64)
CodeDirectory v=20400 size=68869 flags=0x0(none) hashes=2145+3 location=embedded
Signature size=4864
Authority=iPhone Distribution: Tencent Technology (Shenzhen) Company Limited (88L2Q4487U)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=Oct 16, 2019 at 5:54:05 PM
Info.plist entries=21
TeamIdentifier=88L2Q4487U
Sealed Resources version=2 rules=10 files=0
Internal requirements count=1 size=232
- 重签名Frameworks
// 查看钥匙串里可签名的证书
$ security find-identity -v -p codesigning
1) 621E1D12744FBA6B1D37955A14E29E0100A888D9 "Apple Development: 1255058731@qq.com (SB5AG6BQ54)"
1 valid identities found
$ cd /Users/wn/Documents/资料/微信-7.0.8/Payload/WeChat.app/Frameworks
// 对Frameworks目录下的每一个动态库进行重签名
$ codesign -fs "Apple Development: 1255058731@qq.com (SB5AG6BQ54)" andromeda.framework
andromeda.framework: replacing existing signature
$ codesign -fs "Apple Development: 1255058731@qq.com (SB5AG6BQ54)" mars.framework
mars.framework: replacing existing signature
$ codesign -fs "Apple Development: 1255058731@qq.com (SB5AG6BQ54)" marsbridgenetwork.framework
marsbridgenetwork.framework: replacing existing signature
$ codesign -fs "Apple Development: 1255058731@qq.com (SB5AG6BQ54)" matrixreport.framework
matrixreport.framework: replacing existing signature
$ codesign -fs "Apple Development: 1255058731@qq.com (SB5AG6BQ54)" OpenSSL.framework
OpenSSL.framework: replacing existing signature
$ codesign -fs "Apple Development: 1255058731@qq.com (SB5AG6BQ54)" ProtobufLite.framework
ProtobufLite.framework: replacing existing signature
// 返回上级目录
$ cd ..
- 查看可执行文件是否有可执行权限
$ ls -l WeChat
-rwxr-xr-x@ 1 wn staff 126048560 10 16 2019 WeChat
重签名必须要有可执行权限,上面每个地方必须要有- x
新建一个工程
WechatDemo
,注意Team要选择证书1255058731@qq.com (SB5AG6BQ54)
,然后真机编译工程,在Products -> WechatDemo.app -> Show in Finder -> 显示包内容
,获取描述文件embedded.mobileprovision
,把描述文件copy至WeChat包描述文件和BundleID有关,需要修改WeChat包里面
info.plist
的BundleID
com.tencent.xin为上面WechatDemo
工程的BundleID查看
WechatDemo.app
包里面描述文件的权限
$ cd /Users/wn/Library/Developer/Xcode/DerivedData/WechatDemo-dnxucfoasoelktclrmvpnysurhcg/Build/Products/Debug-iphoneos/WechatDemo.app
$ ls
Base.lproj WechatDemo
Info.plist _CodeSignature
PkgInfo embedded.mobileprovision
$ security cms -D -i embedded.mobileprovision
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AppIDName</key>
<string>XC project WechatDemo </string>
<key>ApplicationIdentifierPrefix</key>
<array>
<string>P67NV8GN96</string>
</array>
<key>CreationDate</key>
<date>2021-05-27T14:43:32Z</date>
...
// 查看Entitlements是一个字典,这一块就是权限,是一个plist文件
<key>Entitlements</key>
<dict>
<key>application-identifier</key>
<string>P67NV8GN96.project.WechatDemo</string>
<key>keychain-access-groups</key>
<array>
<string>P67NV8GN96.*</string>
</array>
<key>get-task-allow</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>P67NV8GN96</string>
</dict>
在WechatDemo
工程中新建一个plist文件,名称为Entitlements.plist
,把上面Entitlements
对应的字典内容copy至新建的Entitlements.plist
中,然后把Entitlements.plist
文件copy至WeChat.app
的同一级目录下
- 对
WeChat.app
进行签名
$ cd /Users/wn/Documents/资料/微信-7.0.8/Payload
$ codesign -fs "Apple Development: 1255058731@qq.com (SB5AG6BQ54)" --no-strict --entitlements=Entitlements.plist WeChat.app
WeChat.app: replacing existing signature
8、查看WeChat.app
签名
$ codesign -vv -d WeChat.app
Executable=/Users/wn/Documents/资料/微信-7.0.8/Payload/WeChat.app/WeChat
Identifier=project.SignDemo
Format=app bundle with Mach-O thin (arm64)
CodeDirectory v=20400 size=972596 flags=0x0(none) hashes=30383+7 location=embedded
Signature size=4817
注意这里:此时签名信息已经替换
Authority=Apple Development: 1255058731@qq.com (SB5AG6BQ54)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=May 28, 2021 at 12:09:10 AM
Info.plist entries=68
TeamIdentifier=P67NV8GN96
Sealed Resources version=2 rules=10 files=1470
Internal requirements count=1 size=184
- 把重新签名后的
WeChat.app
安装到手机
- 调试
WeChat.app
Xcode设置Debug - Attach to process - WeChat
三. 使用Xcode调试三方应用
Xcode重签名步骤
- 删除Plugins、Watch
- 重签名Frameworks
- 创建并运行一个同名空工程
- 修改Info.plist中的BundleID改为同名空工程的BundleID
- 利用修改后的app包,替换空工程的app包
- 直接运行
与CodeSign重签名对比少了这三步执行文件权限
、添加描述文件
、通过授权文件重签.app包
创建新工程WeChat
,必须要与微信包同名,否则可能一直运行的是自己创建的app。真机运行完成后 在Products
-> Wechat.app
-> Show in Finder
将product中的WeChat替换成 需要我们上面重签名的WeChat
CMD+R再次真机运行上面创建的WeChat
工程
非越狱环境下载ipa包
怎么获取旧版本的ipa包呢?
苹果官方提供了老版本的iTunes下载,安装了iTunes之后就可以下载app了,注意app后缀有版本号,可以修改后面版本号下载。app包下载完成里面就可以看到ipa包了
旧版iTunes下载网站
iTem2配置
切换bash 和 zsh
$ chsh -s /bin/bash
$ chsh -s /bin/zsh
四. Shell脚本
SHELL脚本介绍
- shell是一种特殊的交互式工具,它为用户提供了启动程序、管理文件系统中文件以及运行在系统上的进程的途径。
- Shell一般是指命令行工具。它允许你输入文本命令,解释命令,并在内核中执行。
- Shell脚本,也就是用各类命令预先放入到一个文本文件中,方便一次性执行的一个脚本文件。
下面我们来练习shell脚本
// 创建目录与文件夹
$ cd /Users/wn/Documents/资料/010--应用重签名原理/代码
$ mkdir shell
$ cd shell/
$ touch 123.txt
// 创建脚本文件,使用脚本创建目录与文件夹
$ cd /Users/wn/Documents/资料/010--应用重签名原理/代码
$ touch 123.sh
// 123.sh 脚本内容如下
mkdir shell
cd shell/
touch 123.txt
// 执行脚本
$ bash 123.sh
// 也可以使用zsh 执行脚本
$ zsh 123.sh
// 使用source执行脚本,会直接进入shell目录
$ source 123.sh
// 在代码目录下执行脚本,发现没有权限
$ ./123.sh
-bash: ./123.sh: Permission denied
// 查看脚本文件的可执行权限
$ ls -l 123.sh
-rw-r--r--@ 1 wn staff 36 5 29 16:39 123.sh
// 对脚本文件添加可执行权限
$ chmod +x 123.sh
// 添加可执行权限之后,成功执行脚本
$ ./123.sh
脚本执行相关命令
-
$source FileName
意思:在当前shell环境中读取并执行FileName中的命令
特点:
- 命令可以强行让一个脚本去立即影响当前的环境(一般用于加载配置文件)。
- 命令会强制执行脚本中的全部命令,而忽略文件的权限。
-
$bash FileName
、$zsh FileName
意思:重新建立一个子shell,在子shell中执行脚本里面的句子。 -
$./FileName
意思:读取并执行文件中的命令。但有一个前提,脚本文件需要有可执行权限。
// 查看mac有多少Shell
$ cd /private/etc
$ cat shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.
/bin/bash macOS默认的shell,仅在MacOS Serial
/bin/csh 被tcsh替换
/bin/dash linux系统比较常见,钨棒图默认的shell
/bin/ksh 兼容bash
/bin/sh 被bash替换
/bin/tcsh 整合csh,提供了更多功能
/bin/zsh 现在MacOS默认的shell
五. 用户组与文件权限
Unix和Linux都是多用户、多任务的系统,所以这样的系统里面就拥有了用户、组的概念。那么同样文件的权限也就有相应的所属用户和所属组了。
Windows与Mac目录结构对比
- Windows中分盘,是单用户
- Mac是多用户,
/
表示让每一个人拥有一块自己独立的区域去做事情,/home
表示用户/usr
表示系统资源
Mac文件属性
上图所示信息分别对应 [ 权限 ] [连接][所有者] [所属组] [文件大小][最后修改日期][文件名称]
文件类型与权限(permission)
权限有10位字符,文件类型与三组文件权限
改变权限:chmod
二进制:r
0100 w
0010 x
0001
符号类型:chmod [u、g、o、a][+(加入)、-(除去)、=(设置)] [r、w、x] 文件名称
-
u
:表示user -
g
:表示group -
o
:表示other -
a
:表示all
// 对123.txt文件进行权限练习
$ cd /Users/wn/Documents/资料/010-- 应用重签名原理/代码/shell
$ ls -l
total 0
-rw-r--r-- 1 wn staff 0 5 29 16:51 123.txt
$ chmod 000 123.txt
$ ls -l
total 0
-rw------- 1 wn staff 0 5 29 16:51 123.txt
// 给所有者添加可执行权限
$ chmod a+x 123.txt
$ ls -l
total 0
-rwx--x--x 1 wn staff 0 5 29 16:51 123.txt
// 注意默认是all
$ chmod +r 123.txt
$ ls -l
total 0
-rwxr-xr-x 1 wn staff 0 5 29 16:51 123.txt
六. 通过shell脚本自动重签名
使用上面创建的空工程WeChat
,在工程中配置shell脚本Build Phase
-> 点击+号
-> New Run Script Phase
,脚本文件会在编译时执行
-
WeChat
工程根目录下创建APP
目录,里面放入上面砸过壳的微信-7.0.8.ipa
包 -
WeChat
工程根目录下创建shell文件:$ touch 123.sh
- 添加脚本执行权限:
$ chmod +x 123.sh
- Run Script 中配置执行脚本命令
./123.sh
123.sh
脚本内容如下,又分成7个步骤
# ${SRCROOT} 它是工程文件所在的目录
TEMP_PATH="${SRCROOT}/Temp"
#资源文件夹,我们提前在工程目录下新建一个APP文件夹,里面放ipa包
ASSETS_PATH="${SRCROOT}/APP"
#目标ipa包路径
TARGET_IPA_PATH="${ASSETS_PATH}/*.ipa"
#清空Temp文件夹
rm -rf "${SRCROOT}/Temp"
mkdir -p "${SRCROOT}/Temp"
#----------------------------------------
# 1. 解压IPA到Temp下
unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH"
# 拿到解压的临时的APP的路径
TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1")
# echo "路径是:$TEMP_APP_PATH"
#----------------------------------------
# 2. 将解压出来的.app拷贝进入工程下
# BUILT_PRODUCTS_DIR 工程生成的APP包的路径
# TARGET_NAME target名称
TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
echo "app路径:$TARGET_APP_PATH"
rm -rf "$TARGET_APP_PATH"
mkdir -p "$TARGET_APP_PATH"
cp -rf "$TEMP_APP_PATH/" "$TARGET_APP_PATH"
#----------------------------------------
# 3. 删除extension和WatchAPP.个人证书没法签名Extention
rm -rf "$TARGET_APP_PATH/PlugIns"
rm -rf "$TARGET_APP_PATH/Watch"
#----------------------------------------
# 4. 更新info.plist文件 CFBundleIdentifier
# 设置:"Set : KEY Value" "目标文件路径"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"
#----------------------------------------
# 5. 给MachO文件上执行权限
# 拿到MachO文件的路径
APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
#上可执行权限
chmod +x "$TARGET_APP_PATH/$APP_BINARY"
#----------------------------------------
# 6. 重签名第三方 FrameWorks
TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks"
if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ];
then
for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
do
# 7. 签名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi
Run Script
中先屏蔽脚本命令 #./123.sh
,把WeChat
运行到真机上,再把脚本放开./123.sh
,再次运行工程,砸过壳的微信-7.0.8.ipa
包成功安装到手机