1. 應用簽名
- 應用簽名原理回顧
上一篇博客“IOS 逆向開發(三)應用簽名”中詳細講解了IOS 應用簽名,證書的原理。本篇博客主要以實戰為主,講解具體如果繞過蘋果證書簽名,給App重簽名,然后可以讓我們的app可以任意安裝到手機。
- 接下來,我將用3種方式來實現對app 的重簽名。
2. App 重簽名 3 種方式
- 其實我們最終簽名app都是使用codesign工具,蘋果也是用xcode集成了這個工具而已。這個工具為我們做了很多事情,而我們只需要敲幾個命令就可以完成重簽名工作。一切看起來都so easy!!!
- 那么,接下來,我們將用三種不同的方式來重簽名App. 我們使用免費證書來重簽名App.
2.0 簽名前準備工作
- 我們重簽名APP,這里簽名的App是使用我們每個人都會使用的重磅級app 微信來重簽名。我使用的版本是微信7.0.8版本
- 我們可以在mac 上面安裝一個叫做PP 助手的工具,這個工具可以下載到你想要的ipa包。其他助手工具也可以,或者你直接沖網上下載。下載微信ipa包
- 先回顧一下上一篇博客“IOS 逆向開發(三)應用簽名”中的開發者證書相關知識。
- 開發者調試安裝app到手機的簽名過程:
- Mac電腦生成公鑰M和私鑰M
- 公鑰M傳給蘋果服務器,蘋果服務器的私鑰A對公鑰M進行加密生成證書返回給xcode
- Xcode下載profile等描述文件,用公鑰M對app進行加密生成app簽名,然后把app簽名和證書以及profile文件一起打包成ipa
- 手機進行兩次解密,手機用手機系統里的公鑰A對證書進行解密得到公鑰M,然后對比profile描述文件,查看權限,看是否合法;然后用公鑰M對app簽名進行解密
手機里的公鑰A與蘋果服務器私鑰A相對應
開發者調試安裝app到手機的簽名過程
- 此外還需要了解一些加密和重簽名相關的命令:
- base64加密文件:
base64 test.txt -o new.txt
- base64解密:
base64 new.txt -o abc.txt -D
- openssl生成私鑰:
openssl genrsa -out private.pem 512
- 由私鑰生成公鑰:
openssl rsa -in private.pem -out public.pem -pubout
- 查看rsa的明文:
openssl rsa -in private.pem -text -out private.text
- 查看csr解密信息:
openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
- 查看profile文件信息:
/Users/mac/Library/MobileDevice/Provisioning\ Profiles 然后security cms -D -i e871987c-b4c5-4658-8338-f6e4cabaff8e.mobileprovision
- 查看簽名信息:ipa包解壓打開,進入Payload,查看.app的簽名信息
codesign -vv -d WeChat.app
- 查看所有證書:
security find-identity -v -p codesigning
- 查看可執行文件macho的加密信息:.app顯示包內容,找到同名的可執行文件otool -l WeChat | grep crypt
$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 輸出文件 輸入文件
將輸入文件壓縮為輸出文件
2.1 利用codesign進行重簽名
- 首先,我們進入我們下載好的WeChat.app所在的目錄,通過命令:
codesign -v -d WeChat.app
來查看一下包的內容
下載的砸核過的越獄應用WeChat 7.0.8信息如下:
我們如果要用codesign這個命令簽名,需要在命令后面跟上證書信息。
-
我們先通過命令:
security find-identity -v -p codesigning
來查看mac電腦的證書信息
查看證書信息 接下來我們進入WeChat.app 查看包里面的內容:
- 我們通過otool工具來查看WeChat可執行文件內容,終端輸入:
otool -l WeChat
:
otool查看WeChat可執行文件信息 - 我們還可以把這些信息重定向到txt文本:終端輸入命令:
otool -l WeChat > ~/Desktop/123.txt
- 此外我們還可以直接通過命令
otool -l WeChat | grep cry
篩選出想要的cryptid內容:
otool -l WeChat 查出來的內容通過管道輸出符,通過grep篩選出 “cry”開頭的內容。
查看cryptid
cryptid == 0 表示沒有進行加密。cryptid == 1表示加密了。這個加密是對稱加密,因為需要對整個app包進行加密,是appstore對其進行加密。
- 我們來思考一個問題,是什么時候進行解密?
是安裝的時候解密還是運行的時候解密呢,為了安全,必須運行時解密,每次運行都需要重新解密一次。這樣雖然會影響運行效率,但是蘋果為了安全不得不在運行時每次對APP進行解密操作。
- 沒有進行加密的app 無法直接在蘋果設備上安裝。
2.1.1 手動進行app重簽名
前面講了這么多,都是在做準備工作,現在我們真正開始重簽名操作。
-
首先,我們進入WeChat.app目錄下面,找到Pluslns目錄,因為普通的插件我們是無法簽名的,所以必須干掉這些插件。
找到Pluslns目錄 然后我們找到Watch目錄。由于Watch目錄下面也有插件,我們也必須干掉。
-
接下來,我們找到Frameworks目錄,需要對該目錄下的所以.framework文件,用我們自己的證書進行簽名操作。
找到Frameworks目錄 -
我們通過命令行,cd 到WeChat.app/Frameworks/目錄下面,通過ls命令查看,有6個framework文件如下:
有6個framework文件 接下來,我要用我自己的證書:"Apple Development: chen lin (QY73GRZ4AG)" 對 上面6個framework分別進行簽名操作。使用命令:
codesign -fs "Apple Development: chen lin (QY73GRZ4AG)" xx框架名稱 .framework
進行簽名。
-
如上圖,這里系統會彈出訪問秘鑰的輸入框,按要求輸入,始終允許即可。輸入你們自己電腦賬號的登錄密碼即可。允許之后,可以看到如下,簽名被替換的消息。
在這里插入圖片描述 -
我們使用同樣的命令,依次對6個framework進行簽名。
依次對6個framework進行簽名 接下來我們來查看一下可執行文件WeChat,那么我們怎么判斷這個可執行文件有權限可以執行呢?
一般我們看這個可執行文件的顏色就可以判斷,黑色是可以有執行權限的,白色是沒有的。
-
我們現在使用
chmod +x WeChat
命令給整個WeChat.app增加可執行權限。
給整個WeChat.app增加可執行權限 接下來,我們還需要對WeChat.app增加描述文件。
-
我們通過新建一個demo工程的方式來申請新的一個描述文件。描述文件無法新增,只能通過從蘋果服務器申請的方式,新建一個工程,xcode會幫助我們申請。
新建一個demo工程的方式來申請新的一個描述文件1
新建一個demo工程的方式來申請新的一個描述文件2 -
描述文件申請了,但是如果沒有連著真機運行,實際上描述文件并沒有下載保存到我們的iphone手機中,所以我們還需要command+R運行一下,在真機上聯調運行一下。
在真機上聯調運行一下 如果這個證書對應的描述文件是第一次在真機iphone上運行,手機系統會彈出信任對話框,讓你信任一下,如果不是第一次,則不會彈框。運行完成后,我們需要的描述文件就進入到了我們的真機iphone中。
-
我們可以從項目WeChatDemo工程的Products/WeChatDemo.app中獲取生成的描述文件。
工程的Products/WeChatDemo.app中獲取生成的描述文件
獲取描述文件 -
得到描述文件后,我們用Command + C 復制這個embedded.mobileprovision描述文件,并Command+V粘貼到微信的WeChat.app目錄下面。這樣我們就給微信app增加了一個我們自己的描述文件。
給微信app增加了一個我們自己的描述文件 -
描述文件拷貝到WeChat.app后,我們還需要修改WeChat.app里面的info.plist里面的描述文件配置,需要bundle identifier 保持一致。
修改WeChat.app里面的info.plist里面的描述文件配置
修改bundle id 接下來,我們還需要簽名整個WeChat.app包,對WeChat.app簽名就需要用到我們剛剛申請的描述文件里面的授權文件了。
我們先把申請的那個描述文件拷貝到WeChat.app同級目錄
-
我們通過命令行:
security cms -Di embedded.mobileprovision
查看一下這個描述文件:
命令行查看描述文件:security cms -Di embedded.mobileprovision 描述文件里面有一個非常重要的東西,這個就是我們權限文件的內容:
-
為了使用方便,我們在我們之前創建的那個demo工程里面新建一個plist文件。
新建一個plist文件
用SourceCode方式打開plist文件
-
我們再確認一下plist文件是否拷貝正確:
確認一下plist文件是否拷貝正確 這樣我們就成功從描述文件中提取出了權限文件到新增的kongyuluWechatEnt.plist文件了。
-
然后我們把這個文件拷貝到WeChat.app同級目錄下面:
拷貝到WeChat.app同級目錄下面 接下來,重要的步驟來了,我們通過命令行,輸入命令:
codesign -fs "證書名稱" --no-strict --entitlements=kongyuluWechatEnt.plist WeChat.app
codesign -fs "Apple Development: chen lin (QY73GRZ4AG)" --no-strict --entitlements=kongyuluWechatEnt.plist WeChat.app
這樣我們就手動簽名就大功告成了,這樣處理過的WeChat.app就會讓蘋果手機認為我們的app 是一個正在開發階段的app,這樣就可以將我們的重簽名過后的app,直接安裝到我們的手機上面去了。
接下來我們可以測試一下,我們重簽名過后的WeChat.app是否可以安裝到手機上面
-
首先打開我們的xcode ,快捷鍵Command + Shift +2 調出設備頁面
快捷鍵Command + Shift +2 調出設備頁面 -
選擇WeChat.app后,會提示是否需要覆蓋安裝,選擇是
覆蓋安裝
- 手動重簽名的步驟有點多,這里再簡單歸納總結一下,總共分為9步:
- 新建工程WeChatDemo,選擇證書和真機調試
- 進入包內容,因為免費證書無法重簽名插件,所以刪除PlugIns文件夾,Watch里也有插件,也刪除
- 對Frameworks里的framework進行重簽名,有些包沒有Frameworks就忽略這步:
進入Frameworks 文件夾;然后一個一個的重簽名
security find-identity -v -p codesigning //查看所有證書
codesign -fs "iPhone Developer: clwmac@icloud.com (Q4M32A5HU5)" QYUniversalFramework.framework //選擇和工程codesignDemo一樣的證書- 給可執行文件執行權限:chmod +x WeChat
- WeChatDemo工程里的Products里的WeChatDemo.app顯示包內容,找到包內容里的embedded.mobileprovision文件,拷貝到需要重簽名的愛奇藝.app包內容中
- WeChatDemo工程的Bundle identifier拷貝到WeChat.app的包內容中的Info.plist的Bundle identifier
- 找到第五步的embedded.mobileprovision文件,然后security cms -D -i embedded.mobileprovision找到<key>Entitlements</key>,然后把<key>Entitlements</key>下面的:
"dict> </dict"
用Xcode生成plist文件PropertyList.plist,然后Open As -> Source Code,把剛才的<dict>拷貝進去,得到如下:- 把第7步得到的plist文件,和WeChat.app放在一個文件夾new中,進行重簽名
- 安裝到手機上
打包為ipa: zip -ry WeChat.ipa new 把new文件夾打包為WeChat.ipa
安裝:Xcode command+shift+2進入到設備管理,選擇+號找到剛才的WeChat.ipa
2.2 利用xcode進行重簽名
- 上面詳細介紹了手動重簽名的過程,這里有很多小伙伴肯定會有疑惑,我們花這么大代價重簽名是為的什么呢?
重簽名app至少有這兩個好處:
- 重簽名后,我們可以通過xcode動態調試那些被我們重簽名過后的app.
- 重簽名后,我們還可以動態注入我們自己的代碼,達到破解的目的。
- 接下來我們將通過xcode來實現重簽名。
- (1)我們先打開xcode ,通過快捷鍵 :“Command + Shift + N”,創建一個新的工程名字叫做WeChat.
- (2) 我們需要先連接真機iphone,將WeChat工程在真機上運行一下。“Command + Shift + R”運行一次。這樣可以得到我們需要的描述文件。然后我們需要拷貝現在的官方微信版本替換掉新建工程Products中的WeChat.app
Products/WeChat.app 通過右鍵Show Finder 可以找到在debug-iphoneos目錄下面,直接替換如下圖:
-
(3) 替換掉之后,我們并不能直接通過xcode運行到真機上面,我還需要完成幾個步驟才行。和手動簽名一樣,首先我們要刪除我們無法簽名的插件信息,刪除WeChat.app下的Watch目錄和 Pluglsn目錄
刪除WeChat.app下的Watch目錄和 Pluglsn目錄 (4)然后,我們還需要對Frameworks目錄下面的所以framework進行重簽名。
- 這樣我們就大功告成了,直接“Command + Shift + R” 運行app,這樣重簽名的微信就可以運行在我們的真機上面,so easy .
注意:這里我們不需要去修改原始微信.app里面的bundle Id ,xcode運行自動會幫我們改為我們新建工程的bundle id.
- 這里我們對xcode重簽名步驟總結一下:
- 新建工程WeChat,選擇證書和真機調試
- 把WeChat.app替換WeChat工程的Products的WeChat.app
- 進入替換后的WeChat.app包內容中,刪除PlugIns文件夾和Watch文件夾
- 重簽名對Frameworks里的framework進行重簽名,有些包沒有Frameworks就忽略這步
- 改替換后的WeChat.app包中的Info.plist的Bundle identifier改為WeChat工程的Bundle identifier
- 給可執行文件執行權限:chmod +x WeChat
- 運行工程WeChat
注意: 這里如果新建的工程名字和你要簽名的app名稱不一致,會簽名失敗,運行的還是你新建工程的那個demo,而不是你想覆蓋的微信.app。因為xcode運行時,會自動將可執行文件改為你新建工程的名稱。加入我們新建的工程名稱叫demo,我們用WeChat.app改名后替換了demo.app,運行的時候會自動運行demo.app而不是WeChat.app. 這樣我們需要通過運行腳本的方式,來更加優雅的執行重簽名操作。
- 我們下面將講述通過Shell腳本來重簽名。
2.3 利用shell腳本進行重簽名
- 新建工程cosignAutoDemo,選擇證書和真機調試,在工程根目錄里新建APP和Temp文件夾:
- xcode->Build Phases->+New Run Script Phase
- 在Run Script的shell代碼如下:
# ${SRCROOT} 它是工程文件所在的目錄
TEMP_PATH="${SRCROOT}/Temp"
#資源文件夾
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
- 在APP文件夾下放ipa包,然后運行.這樣就大功告成了,是不是更簡單呢?
- 其實,我們也可以把腳本保存成xcodeCodesign.sh文件,然后在Run Script的shell的代碼處,寫入xcodeCodesign.sh文件的路徑;最后要chmod +x xcodeCodesign.sh,就可以運行了。
- 下面將介紹一種更簡單的方法,名字叫做第三方,第三方基本上就是傻瓜式的了,安裝官方說明就可以完成了。
2.4 利用第三方工具 MonkeyDev重簽名
- MonkeyDev安裝,點擊這里下載
- 新建MonkeyApp工程monkeyDemo
- 在monkeyDemo文件夾的TargetApp里放ipa包,然后運行