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包。其他助手工具也可以,或者你直接衝網上下載。
- 先回顧一下上一篇部落格“IOS 逆向開發(三)應用簽名”中的開發者證書相關知識。
- 開發者除錯安裝app到手機的簽名過程:
- Mac電腦生成公鑰M和私鑰M
- 公鑰M傳給蘋果伺服器,蘋果伺服器的私鑰A對公鑰M進行加密生成證書返回給xcode
- Xcode下載profile等描述檔案,用公鑰M對app進行加密生成app簽名,然後把app簽名和證書以及profile檔案一起打包成ipa
- 手機進行兩次解密,手機用手機系統裡的公鑰A對證書進行解密得到公鑰M,然後對比profile描述檔案,檢視許可權,看是否合法;然後用公鑰M對app簽名進行解密
- 手機裡的公鑰A與蘋果伺服器私鑰A相對應
- 此外還需要了解一些加密和重簽名相關的命令:
- 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
: - 我們還可以把這些資訊重定向到txt文字:終端輸入命令:
otool -l WeChat > ~/Desktop/123.txt
- 此外我們還可以直接通過命令
otool -l WeChat | grep cry
篩選出想要的cryptid內容:
otool -l WeChat 查出來的內容通過管道輸出符,通過grep篩選出 “cry”開頭的內容。
cryptid == 0 表示沒有進行加密。cryptid == 1表示加密了。這個加密是對稱加密,因為需要對整個app包進行加密,是appstore對其進行加密。
- 我們來思考一個問題,是什麼時候進行解密?
是安裝的時候解密還是執行的時候解密呢,為了安全,必須執行時解密,每次執行都需要重新解密一次。這樣雖然會影響執行效率,但是蘋果為了安全不得不在執行時每次對APP進行解密操作。
- 沒有進行加密的app 無法直接在蘋果裝置上安裝。
2.1.1 手動進行app重簽名
-
前面講了這麼多,都是在做準備工作,現在我們真正開始重簽名操作。
-
首先,我們進入WeChat.app目錄下面,找到Pluslns目錄,因為普通的外掛我們是無法簽名的,所以必須幹掉這些外掛。
-
然後我們找到Watch目錄。由於Watch目錄下面也有外掛,我們也必須幹掉。
-
接下來,我們找到Frameworks目錄,需要對該目錄下的所以.framework檔案,用我們自己的證書進行簽名操作。
-
我們通過命令列,cd 到WeChat.app/Frameworks/目錄下面,通過ls命令檢視,有6個framework檔案如下:
-
接下來,我要用我自己的證書:"Apple Development: chen lin (QY73GRZ4AG)" 對 上面6個framework分別進行簽名操作。使用命令:
codesign -fs "Apple Development: chen lin (QY73GRZ4AG)" xx框架名稱 .framework
進行簽名。
-
如上圖,這裡系統會彈出訪問祕鑰的輸入框,按要求輸入,始終允許即可。輸入你們自己電腦賬號的登入密碼即可。允許之後,可以看到如下,簽名被替換的訊息。
-
我們使用同樣的命令,依次對6個framework進行簽名。
-
接下來我們來檢視一下可執行檔案WeChat,那麼我們怎麼判斷這個可執行檔案有許可權可以執行呢?
一般我們看這個可執行檔案的顏色就可以判斷,黑色是可以有執行許可權的,白色是沒有的。
-
我們現在使用
chmod +x WeChat
命令給整個WeChat.app增加可執行許可權。 -
接下來,我們還需要對WeChat.app增加描述檔案。
-
我們通過新建一個demo工程的方式來申請新的一個描述檔案。描述檔案無法新增,只能通過從蘋果伺服器申請的方式,新建一個工程,xcode會幫助我們申請。
-
描述檔案申請了,但是如果沒有連著真機執行,實際上描述檔案並沒有下載儲存到我們的iphone手機中,所以我們還需要command+R執行一下,在真機上聯調執行一下。
-
如果這個證書對應的描述檔案是第一次在真機iphone上執行,手機系統會彈出信任對話方塊,讓你信任一下,如果不是第一次,則不會彈框。執行完成後,我們需要的描述檔案就進入到了我們的真機iphone中。
-
我們可以從專案WeChatDemo工程的Products/WeChatDemo.app中獲取生成的描述檔案。
-
得到描述檔案後,我們用Command + C 複製這個embedded.mobileprovision描述檔案,並Command+V貼上到微信的WeChat.app目錄下面。這樣我們就給微信app增加了一個我們自己的描述檔案。
-
描述檔案拷貝到WeChat.app後,我們還需要修改WeChat.app裡面的info.plist裡面的描述檔案配置,需要bundle identifier 保持一致。
-
接下來,我們還需要簽名整個WeChat.app包,對WeChat.app簽名就需要用到我們剛剛申請的描述檔案裡面的授權檔案了。
-
我們先把申請的那個描述檔案拷貝到WeChat.app同級目錄
-
我們通過命令列:
security cms -Di embedded.mobileprovision
檢視一下這個描述檔案: -
描述檔案裡面有一個非常重要的東西,這個就是我們許可權檔案的內容:
- 為了使用方便,我們在我們之前建立的那個demo工程裡面新建一個plist檔案。
-
我們再確認一下plist檔案是否拷貝正確:
-
這樣我們就成功從描述檔案中提取出了許可權檔案到新增的kongyuluWechatEnt.plist檔案了。
-
然後我們把這個檔案拷貝到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 調出裝置頁面
-
選擇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找到Entitlements,然後把Entitlements下面的: "dict> </dict" 用Xcode生成plist檔案PropertyList.plist,然後Open As -> Source Code,把剛才的拷貝進去,得到如下:
- 把第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目錄
-
(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包,然後執行