在重簽名之前,我們首先要了解一個工具:codesign
。
-
codesign
Xcode提供的簽名工具,codesign
,我們利用它通過幾個命令就可以完成重簽名。
一、手動重簽名
首先我們需要砸殼的ipa
包,如何獲取砸殼包我們稍后會講。
1、刪除插件和帶有插件的.app
包(比如watch)
2、對Frameworks里面的庫進行重簽名
3、給可執行文件 +x
,也就是添加可執行權限
4、添加描述文件(新建工程,真機編譯得到,而且要運行,將描述文件安裝到手機)
5、替換BundleID
(在info.plist
文件中,BundleID
要與描述文件中的ID
保持一致)
6、通過授權文件(Entilements
)重簽.app包
:
① . 查看描述文件$security cms -D -i embedded.mobileprovision
② . 將描述文件中的Entilements
拷貝出來,生成plist
文件。(文件名稱為:entitlements.plist
)
③ . 用權限文件簽名.app
包 : $ codesign -fs "Apple Development: XX(XX)" --no-strict --entitlements=entitlements.plist xxx.app
7、最后通過Xcode安裝
-
1、刪除插件和帶有插件的
.app
包(比如watch)
首先我們找到一個叫Pluglns
的文件夾,里面裝的是一些插件。可以直接將這個文件夾刪除。
如果APP有適配Apple Wacth
,那么把Watch
文件夾也一并刪掉。
這么做是因為,我們使用的免費的證書是無法對插件進行重簽名的,Watch
里面也會包含一些插件。 -
2、對Frameworks里面的庫進行重簽名
在對Frameworks
里面的庫進行重簽名之前,我們需要選擇一個可簽名的證書。利用下面的指令查看鑰匙串里面可簽名的證書:
$ security find-identity -v -p codesigning
選擇其中一個對庫文件進行重簽名。
- 比如我們現在的
Frameworks
文件夾里面有OpenSSL.framework
這個庫,那么我們對這個庫進行一下重簽名
$ Codesign -fs "Apple Development: xxxx (xxxx)" OpenSSL.framework
-
3、給可執行文件 +x,也就是添加可執行權限
首先我們可以通過下面的指令來查看可執行文件的權限:
$ ls -l <可執行文件名>
***********
輸出的內容里面會有這樣字段字符串
`-rwxr-xr-x`
* 最前面的`-` :這個位置代表文件類型,
`d`代表目錄(directory)、 `-`代表文件
* 后面跟著的是文件權限
`r` --> read,可讀權限 / `w` --> write,可寫權限 / `x` --> execute,可執行權限。
注意:這三個權限的位置不會變,依次是`rwx`,出現`-`在對應的位置,代表沒有此權限。
* 一個文件的完整權限,總共分為三組:
* 第一組:文件所有者的權限
* 第二組:這一組其他用戶的權限
* 第三組:非本組用戶的權限
-
改變權限:chmod
我們可以使用chmod
命令來改變文件的權限。設置的方法有兩種:數字類型改變 & 符號類型改變。
由于文件權限分為:三種身份:user
/group
/other
、三個權限read
/write
/execute
所以整體的設置如下:-
數字類型改變
各個權限數字對照:r:4
/w:2
/x:1
,其實就是左移運算。
如果一個文件權限問[-rwxr-xr-x]
User:4+2+1 = 7
Group:4+0+1 = 5
Other:4+0+1 = 5
則命令為:chmod 755 <文件名>
image.png - 符號類型改變
-
數字類型改變
$ chmod <u、g、o、a> <+、-、=> <r、w、x> <文件名>
*******************
u:user
g:group
o:other
a:all
+:加入
-:除去
=:設置
*******************
比如給所有的用戶添加 `可執行` 權限,可以這樣寫:
$ chmod a+x <文件名>
還可以這樣寫
$ chmod +x <文件名>
因為默認是給所有用戶添加。
-
4、添加描述文件(新建工程,真機編譯得到,而且要運行,將描述文件安裝到手機)
這一步就是自行創建一個Demo,然后運行到手機上面就可以了。作用是將描述文件安裝到手機上面。
?? 注意:拉取免費證書的時候,要使用跟上面Frameworks
簽名時用到的開發者賬號保持一致。 -
5、替換BundleID(在info.plist文件中,BundleID要與描述文件中的ID保持一致)
在APP包里面,找到plist
文件,替換里面的BundleID
,要跟我們的Demo里面的保持一致。因為我們的描述文件是跟BundleID
關聯的。 -
6、通過授權文件(Entilements)重簽.app包
在我們上面創建的Demo的APP包里面,我們會找名為embedded.mobileprovision
的文件,這就是我們需要的描述文件:
① . 查看描述文件$security cms -D -i embedded.mobileprovision
我們會發現,描述文件的本質就是plist
文件:
② . 將描述文件中的Entilements
拷貝出來,生成plist
文件。(文件名稱為:entitlements.plist
)
注意:只拷貝dict
里面的內容
Entilements
新建plist
,命名為entitlements.plist
,并將上面拷貝的內容,賦值進入新創建的plist
文件中:
③ . 用權限文件簽名.app
包 :$ codesign -fs "Apple Development: XXX(XXX)" --no-strict --entitlements=entitlements.plist xxx.app
這一步是對整個MachO
文件進行簽名。
?? 注意:我們第③步的指令的前提是,第②步生成的entitlements.plist
文件,跟xxx.app
包在同一層級。 -
7、最后通過Xcode安裝
注意,這個時候我們的Demo已經在手機上運行過了,證書也已經被認證過了。同時我們的APP包,在第6步的時候也已經通過描述文件進行了簽名。
這個時候,我們可以通過Xcode的Window ---> Devices & Simulators
,將我們修改后的APP包安裝到手機上面。
以上就是我們手動重簽名的整個過程,在整個過程中有幾點需要注意:
1、使用的開發者賬號要始終保持一致
2、BunldID
要記得修改,跟Demo里面的保持一致。(這一點比較容易被忘記)
3、需要重簽名的地方有三個:Frameworks
、可執行文件
、APP包
我們再完成了APP的安裝之后,下一步就是調試。這里我們當然還是利用Xcode進行調試。在Debug ---> Attach to Process
中找到我們剛剛安裝的APP,這樣就可以進行調試了。(?????? 警告:如果你使用的類似于微信這樣的APP,在調試的過程中要注意了,賬號很可能會被鎖,不要冒險使用自己的賬號。)
二、手動結合Xcode重簽名
這種辦法其實是在第一種方法的基礎上進行的,上面方法的 1,2,3
步還是要做的。之后只需要將APP包拷貝進Xcode工程目錄下就可以了,剩下的就交個Xcode。我們只需運行工程就可以了。
三、利用shell腳本重簽名
shell
腳本如下(一定要仔細閱讀腳本,所有的注釋都在里面):
# ${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
#簽名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi