IOS 逆向開發(四)App重簽名

孔雨露發表於2020-04-06

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包

下載微信7.0.8版本

  1. Mac電腦生成公鑰M和私鑰M
  2. 公鑰M傳給蘋果伺服器,蘋果伺服器的私鑰A對公鑰M進行加密生成證書返回給xcode
  3. Xcode下載profile等描述檔案,用公鑰M對app進行加密生成app簽名,然後把app簽名和證書以及profile檔案一起打包成ipa
  4. 手機進行兩次解密,手機用手機系統裡的公鑰A對證書進行解密得到公鑰M,然後對比profile描述檔案,檢視許可權,看是否合法;然後用公鑰M對app簽名進行解密
  5. 手機裡的公鑰A與蘋果伺服器私鑰A相對應
    開發者除錯安裝app到手機的簽名過程
  • 此外還需要了解一些加密和重簽名相關的命令:
  1. base64加密檔案:base64 test.txt -o new.txt
  2. base64解密: base64 new.txt -o abc.txt -D
  3. openssl生成私鑰:openssl genrsa -out private.pem 512
  4. 由私鑰生成公鑰: openssl rsa -in private.pem -out public.pem -pubout
  5. 檢視rsa的明文:openssl rsa -in private.pem -text -out private.text
  6. 檢視csr解密資訊:openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
  7. 檢視profile檔案資訊: /Users/mac/Library/MobileDevice/Provisioning\ Profiles 然後security cms -D -i e871987c-b4c5-4658-8338-f6e4cabaff8e.mobileprovision
  8. 檢視簽名資訊:ipa包解壓開啟,進入Payload,檢視.app的簽名資訊codesign -vv -d WeChat.app
  9. 檢視所有證書:security find-identity -v -p codesigning
  10. 檢視可執行檔案macho的加密資訊:.app顯示包內容,找到同名的可執行檔案otool -l WeChat | grep crypt
  11. $security find-identity -v -p codesigning 列出鑰匙串裡可簽名的證書
  12. $Codesign –fs “證書串” 檔名 強制替換籤名
  13. $Chmod +x 可執行檔案 給檔案新增許可權
  14. $security cms -D -i ../embedded.mobileprovision 檢視描述檔案
  15. $codesign -fs “證書串” --no-strict --entitlements=許可權檔案.plist APP包
  16. $Zip –ry 輸出檔案 輸入檔案 將輸入檔案壓縮為輸出檔案

2.1 利用codesign進行重簽名

  • 首先,我們進入我們下載好的WeChat.app所在的目錄,通過命令:codesign -v -d WeChat.app 來檢視一下包的內容

下載的砸核過的越獄應用WeChat 7.0.8資訊如下:

檢視WeChat.app包內容

  • 我們如果要用codesign這個命令簽名,需要在命令後面跟上證書資訊。

  • 我們先通過命令:security find-identity -v -p codesigning 來檢視mac電腦的證書資訊

    檢視證書資訊

  • 接下來我們進入WeChat.app 檢視包裡面的內容:

找到我們的WeChat mach-o可執行檔案

  • 我們通過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目錄下面也有外掛,我們也必須幹掉。

刪除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 進行簽名。

codesign -fs 對框架進行簽名

  • 如上圖,這裡系統會彈出訪問祕鑰的輸入框,按要求輸入,始終允許即可。輸入你們自己電腦賬號的登入密碼即可。允許之後,可以看到如下,簽名被替換的訊息。

    在這裡插入圖片描述

  • 我們使用同樣的命令,依次對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同級目錄

描述檔案拷貝到WeChat.app同級目錄

  • 我們通過命令列:security cms -Di embedded.mobileprovision檢視一下這個描述檔案:

    命令列檢視描述檔案:security cms -Di embedded.mobileprovision

  • 描述檔案裡面有一個非常重要的東西,這個就是我們許可權檔案的內容:

許可權檔案內容

  • 為了使用方便,我們在我們之前建立的那個demo工程裡面新建一個plist檔案。
    新建一個plist檔案
    用SourceCode方式開啟plist檔案

拷貝許可權檔案內到新建的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進行簽名

  • 這樣我們就手動簽名就大功告成了,這樣處理過的WeChat.app就會讓蘋果手機認為我們的app 是一個正在開發階段的app,這樣就可以將我們的重簽名過後的app,直接安裝到我們的手機上面去了。

  • 接下來我們可以測試一下,我們重簽名過後的WeChat.app是否可以安裝到手機上面

  • 首先開啟我們的xcode ,快捷鍵Command + Shift +2 調出裝置頁面

    快捷鍵Command + Shift +2 調出裝置頁面

  • 選擇WeChat.app後,會提示是否需要覆蓋安裝,選擇是

    覆蓋安裝

安裝重簽名包

  • 手動重簽名的步驟有點多,這裡再簡單歸納總結一下,總共分為9步:
  1. 新建工程WeChatDemo,選擇證書和真機除錯
  2. 進入包內容,因為免費證書無法重簽名外掛,所以刪除PlugIns資料夾,Watch裡也有外掛,也刪除
  3. 對Frameworks裡的framework進行重簽名,有些包沒有Frameworks就忽略這步: 進入Frameworks 資料夾;然後一個一個的重簽名 security find-identity -v -p codesigning //檢視所有證書 codesign -fs "iPhone Developer: clwmac@icloud.com (Q4M32A5HU5)" QYUniversalFramework.framework //選擇和工程codesignDemo一樣的證書
  4. 給可執行檔案執行許可權:chmod +x WeChat
  5. WeChatDemo工程裡的Products裡的WeChatDemo.app顯示包內容,找到包內容裡的embedded.mobileprovision檔案,拷貝到需要重簽名的愛奇藝.app包內容中
  6. WeChatDemo工程的Bundle identifier拷貝到WeChat.app的包內容中的Info.plist的Bundle identifier
  7. 找到第五步的embedded.mobileprovision檔案,然後security cms -D -i embedded.mobileprovision找到Entitlements,然後把Entitlements下面的: "dict> </dict" 用Xcode生成plist檔案PropertyList.plist,然後Open As -> Source Code,把剛才的拷貝進去,得到如下:
  8. 把第7步得到的plist檔案,和WeChat.app放在一個資料夾new中,進行重簽名
  9. 安裝到手機上 打包為ipa: zip -ry WeChat.ipa new 把new資料夾打包為WeChat.ipa 安裝:Xcode command+shift+2進入到裝置管理,選擇+號找到剛才的WeChat.ipa

2.2 利用xcode進行重簽名

  • 上面詳細介紹了手動重簽名的過程,這裡有很多小夥伴肯定會有疑惑,我們花這麼大代價重簽名是為的什麼呢?

重簽名app至少有這兩個好處:

  1. 重簽名後,我們可以通過xcode動態除錯那些被我們重簽名過後的app.
  2. 重簽名後,我們還可以動態注入我們自己的程式碼,達到破解的目的。
  • 接下來我們將通過xcode來實現重簽名。
  • (1)我們先開啟xcode ,通過快捷鍵 :“Command + Shift + N”,建立一個新的工程名字叫做WeChat.

建立一個新的工程名字叫做WeChat

  • (2) 我們需要先連線真機iphone,將WeChat工程在真機上執行一下。“Command + Shift + R”執行一次。這樣可以得到我們需要的描述檔案。然後我們需要拷貝現在的官方微信版本替換掉新建工程Products中的WeChat.app

替換掉新建工程Products中的WeChat.app

Products/WeChat.app 通過右鍵Show Finder 可以找到在debug-iphoneos目錄下面,直接替換如下圖:

在這裡插入圖片描述

  • (3) 替換掉之後,我們並不能直接通過xcode執行到真機上面,我還需要完成幾個步驟才行。和手動簽名一樣,首先我們要刪除我們無法簽名的外掛資訊,刪除WeChat.app下的Watch目錄和 Pluglsn目錄

    刪除WeChat.app下的Watch目錄和 Pluglsn目錄

  • (4)然後,我們還需要對Frameworks目錄下面的所以framework進行重簽名。

對Frameworks目錄下面的所以framework進行重簽名

對6個framework進行重簽名

  • 這樣我們就大功告成了,直接“Command + Shift + R” 執行app,這樣重簽名的微信就可以執行在我們的真機上面,so easy .

注意:這裡我們不需要去修改原始微信.app裡面的bundle Id ,xcode執行自動會幫我們改為我們新建工程的bundle id.

重簽名成功後的微信

  • 這裡我們對xcode重簽名步驟總結一下:
  1. 新建工程WeChat,選擇證書和真機除錯
  2. 把WeChat.app替換WeChat工程的Products的WeChat.app
  3. 進入替換後的WeChat.app包內容中,刪除PlugIns資料夾和Watch資料夾
  4. 重簽名對Frameworks裡的framework進行重簽名,有些包沒有Frameworks就忽略這步
  5. 改替換後的WeChat.app包中的Info.plist的Bundle identifier改為WeChat工程的Bundle identifier
  6. 給可執行檔案執行許可權:chmod +x WeChat
  7. 執行工程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重簽名

  1. MonkeyDev安裝,點選這裡下載
  2. 新建MonkeyApp工程monkeyDemo
  3. 在monkeyDemo資料夾的TargetApp裡放ipa包,然後執行

相關文章