iOS逆向 - shell 腳本自動重簽名與代碼注入

前言:

本篇文章創建在上篇博客 :shell

iOS逆向 - 應用簽名原理及重簽名 (重籤微信應用實戰) 的基礎知識之上的 , 不瞭解的同窗歡迎去閱讀 . 本篇會講述如何利用 shell 腳本自動重簽名和應用調試 .數據庫

若是篇幅不過長的話 , 咱們再來玩一玩代碼注入 .bash

另外 筆者使用的是 Xcode 11 , 因此 Xcode 新版本目前沒發現有問題 . 同樣玩 .微信

利用 Xcode 重簽名和調試

這裏之因此要用 Xcode 來作一次重籤 , 有如下幾個目的 :app

  • 節省本身建立描述文件 / 重簽名應用的步驟 .
  • 有了工程能夠看獲得部分打印.
  • 方便咱們本身添加代碼運行 .
  • ... 等等

利用 Xcode 重籤的原理和上篇博客中基本同樣 ( 由於咱們也提到過 , Xcode 自己也就是利用 codeSign 來作的 ) , 所以 , 我這邊快速過一遍 , 不過多講述了 .函數

步驟 1 : 新建同名工程

之因此要用同名工程 , 由於是有一些坑的 .工具

( 不使用同名工程時 , 每次 build 會從新建立一個 Mach-O , 也就是說此時你就算更換了包 , 可是這個包裏有兩個 Mach-O , 而運行的還會是你本身的空工程 , 因此在咱們已經下載到 ipa 看獲得包裏的 Mach-O 的狀況下 , 咱們就起和它同樣的名字就好 )post

ok , 新建工程 , 選擇開發者 , 選擇真機 , 直接 run .ui

run 成功以後查看生產的 appspa

看完前面一篇博客的同窗應該都清楚 , 這一步是爲了把描述文件安裝到手機裏 .

步驟 2 : 替換 App 包

找到以前從pp助手裏下載好的 已經砸過殼的微信應用包 , 直接替換.

步驟 3 : 刪插件

這一步跟咱們以前本身純手動操做同樣 .

  • 打開 WeChat , 顯示包內容 . 找到 PlugIns 文件夾, 直接刪除 插件普通帳號是籤不了的 .

  • 找到 Watch 文件夾 , 由於這裏也有插件 , 咱們暫時不須要 Watch , 直接刪掉 .

步驟 4 : 重籤 FrameWork

進入 FrameWork 文件夾

利用 CodeSign , 使用咱們的證書進行重簽名.

codesign -fs "複製的你本身的證書名字" 要重籤的FrameWork名稱
複製代碼

例如:

codesign -fs "iPhone Developer: ha ha (123456)" andromeda.framework
複製代碼

FrameWork 文件夾下全部的庫所有重籤.

注意 ⚠️:

這個時候 App 包裏的Bundle ID 仍是微信的 ,可是咱們先不改 , 直接運行 .

重籤成功

注意看本來咱們的空工程 , 在手機上已經安裝上了微信的包 ,

那麼你再去查看微信包裏的 Info.plist 裏的 Bundle ID , 已經被自動替換成咱們的包名了 .

那麼對比一下咱們純手寫的重籤 , 這個顯然更加簡單且實用 . 可是每次重籤都這麼搞一下也不太合適 , 當咱們理解了重籤原理以後 , 就沒有必要每次這麼搞了 .

並且我也不必定能保證我確實是同名工程 , 我但願我隨便叫什麼名字均可以重籤 .

ok. 進入 Shell 部分 .

利用 Shell 腳本自動重簽名

Shell 以及 Shell 腳本

爲了統一你們前導知識的前提 , 咱們仍是先來介紹下 SHELL 腳本 , 已經熟悉的同窗能夠自行跳過 .

  • Shell 是一種特殊的交互式工具,它爲用戶提供了啓動程序、管理文件系統中文件以及運行在系統上的進程的途徑。

  • Shell 通常是指命令行工具。它容許你輸入文本命令,而後解釋命令,並在內核中執行。

  • Shell 腳本,也就是用各種命令預先放入到一個文本文件中,方便一次性執行的一個腳本文件。

簡單來講 , 你們能夠理解爲咱們平時在 終端 / iTerm2 中寫的命令的集合 . 固然 , 它就必不可少的設計到環境變量和權限等問題 .

MAC 系統中 , 默認使用的 shellbash . 咱們使用 iTerm 的時候 , 常常會配置另外一個 shellzsh . 固然 , 還有一些其餘的 shell .

咱們須要知道的是 bash 的初始化文件是家目錄下的 .bash_profile zsh 的初始化文件一樣是家目錄下的 .zshrc . 裏面配置了一些環境變量.

寫一個簡單的 shell 腳本

例如咱們常常有如下操做 :

mkdir test
cd test
touch 123.txt
cd ..
複製代碼

那麼咱們想將這些指令打包在一塊兒 , 統一運行 . 相似於數據庫中事務同樣 .

輸入命令 :

vi 123.sh
複製代碼

輸入文件內容:

mkdir test
cd test
touch 123.txt
複製代碼

好 , 此時 咱們已經生成了一個最簡單的腳本 123.sh .

那麼如何執行呢 . 方法有不少種

    1. 使用 MAC 自帶的 bash shell :
    bash 123.sh
    複製代碼

腳本執行完 , 咱們的文件也建立好了 .

    1. zsh
    zsh 123.sh
    複製代碼
    1. source
    source 123.sh
    複製代碼
    1. ./
    ./123.sh
    複製代碼

注意 :

source執行完以後停留在子目錄裏 .

./ 可能會報沒有執行權限的問題 . +x 便可

區別

  • $source FileName

    • 意思:在當前 shell 環境中讀取並執行 FileName 中的命令
    • 特色:
      • 命令能夠強行讓一個腳本去當即影響當前的環境(通常用於加載配置文件)。
      • 命令會強制執行腳本中的所有命令,而忽略文件的權限。
  • $bash FileName / $zsh FileName

    • 意思:從新創建一個子 shell,在子 shell 中執行腳本里面的句子。
  • $./FileName

    • 意思:讀取並執行文件中的命令。但有一個前提,腳本文件須要有可執行權限。

shell 重簽名

步驟 1. 新建工程

名稱隨意 , 新建完畢選擇開發者 . 證書 
複製代碼

運行一下空工程 ( 將描述文件安裝到手機上 )

步驟 2. 準備要重籤的包

  • 在工程根目錄下新建 APP 文件夾 , 也能夠起其餘名稱 , 與 Shell 腳本中的文件名對應起來就能夠.
  • 將下載好的砸殼應用 ipa 放入 APP 文件夾中.

步驟 3. 新建 Run Script Phase

能夠看到他默認使用的是 shshell .

固然 你們能夠先隨便寫點 而後 build 一下看看有沒有執行.

開始編寫腳本 :

 # ${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文件的路徑WeChat
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
複製代碼

腳本中步驟都有詳細註釋說明. 那麼咱們來總結一下這個腳本作了什麼.

其實跟咱們手動重籤的步驟是如出一轍的.

  • 1 在工程跟目錄中找到 APP 文件夾. 找到裏面的後綴爲 .ipa 的文件路徑 , 建立並清空 Temp 文件夾 . (以便後面存放解壓ipa包的內容)

  • 2 將 ipa 解壓到 Temp 路徑中 , 找到其中 app 包的路徑. ( Palyod 裏的 .app 包) 並將解壓出來的 .app 包拷貝進入工程下 ( 其實就是替換掉工程 build 產生的.app 包)

  • 3 刪除 PlugInsWatchAPP.

  • 4 更新 info.plist 文件 CFBundleIdentifier

  • 5 給 MachO 文件上執行權限

  • 6 重簽名第三方 FrameWorks

( shell 中添加 echo 能夠進行打印輸出 , 在 build 記錄中 )

固然 , 你能夠直接在 Run Script Phase 裏寫完這些 shell , 也能夠寫到一個 app.sh 腳本文件中 , 而後在 Run Script Phase 裏寫一個 ./app.sh 便可 .

若是你遇到

相信你已經知道怎麼解決了. 是的 chmod +x app.sh

重籤成功 !

framework 代碼注入

通常修改原始的程序,是利用代碼注入的方式,注入代碼就會選擇利用 FrameWork 或者 Dylib 等三方庫的方式注入。

固然 , 也能夠直接修改 Mach-O 文件 , 這個涉及到彙編以及二進制 , 後面會考慮要不要繼續解讀 .

首先咱們須要知道的是 Mach-O 文件擁有固定的格式 , 而對於 iOS 系統應用來講 , 須要經過 dyld 去讀取 Mach-O , 從而決定文件包須要加載哪些庫 , 如何去加載等等 ,

後續我會專門講一講 Mach-O 文件 以及 dyld 連接流程 和 符號表的一些內容.

使用 MachOView 可視化預覽 Mach-O 文件內容 ( otools 命令也能夠 ) .

那麼所以 , 咱們能夠思考 :

若是我能夠修改 Mach-O 文件的 Load Commands ( 加載指令 , 就是告訴 dyld 如何去加載 ) , 往其中添加一條 , 添加一條指令讓其去加載 咱們本身生成的 framework , 是否可行呢 .

答案是確定的 .

步驟 1 : 工程準備

準備好已經重簽完的工程 或者上述 準備好了 shellipa 的工程.

步驟 2 : 新建 framework

File - New - TargetCocoa Touch Framework , 我這裏取名 LBHook

步驟 3 : framework 中新建一個類

.m 文件中寫 load 方法 .

熟悉 load 方法機制的同窗都知道 , load 方法是在 main 函數以前 , dyld 加載 _objc_init 時就會調用的. ( 不清楚的同窗能夠去閱讀一下 iOS load方法調用機制解析 這篇文章 )

步驟 4 : cmd + B 編譯一下

編譯後打開包內容 , 查看 Frameworks 文件夾 , 能夠看到咱們的 framework 已經放進去了 .

可是沒用啊 , 微信的 Mach-O 的 加載指令 load Commands 裏並不會去加載個人這個庫 .

步驟 5 : 修改 Mach-O

  • 給當前 Mach-O 添加指令 讓其加載咱們的 framework . 這裏要使用一個工具 yololib 提取碼 : wxvv

  • 下載完畢後 , 將其複製到 usr/local/bin 中 , 這樣環境變量就能夠在任意路徑下使用 yololib 了.

  • 隨便找一個 Mach-O 文件 , go2shell , 或者手動 cd 到這個目錄.

  • yololib Wechat Frameworks/你的framework名稱路徑/你的framework

    • 例 : yololib Wechat Frameworks/LBHook.framework/LBHook
    • 注意 這個 framework 路徑是至關於前面 macho 文件的路徑 .

修改完畢後能夠利用 MachOView 來看下咱們的加載指令添加進去了沒.

  • 那麼實驗完畢能夠添加指令 , 咱們就來修改一下微信的原包裏的 Mach-O , 讓其加載咱們的 framework .
  • 打開咱們 APP 路徑下的 ipa 包 , 改成 zip , 解壓 , Payload 裏的包 , 顯示包內容 , 找到 Mach-O .
  • yololib Wechat Frameworks/LBHook.framework/LBHook
  • 修改完畢後 從新壓縮 使用 zip -ry Wechat.ipa Payload ( 其實不從新壓縮也能夠 跟咱們 shell 腳本里對應起來就行了 ) .

見證奇蹟的時刻 :

cmd + r 運行 . 看控制檯打印

思考題

那麼既然咱們能夠注入代碼 . 那咱們能夠作什麼 ?

給個思路 :

能夠注入代碼 , 咱們就能夠 hook 微信的方法 . 上一篇文章我提到過 view Debug , 咱們是能夠看獲得點擊 登陸 / 註冊 的時候 , 調用的具體是什麼方法的 . 又有黑魔法的存在 , 咱們能夠作的不少 . 你們本身去玩 .

補充

  • 代碼注入時修改 Mach-O 的 load commands 咱們是使用手動注入的 . 其實咱們在把 yololib 環境變量配置好以後 , 徹底能夠在以前的 shell 腳本里作注入 .
    • 上面 shell 腳本中最後一行 加上
    • yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/HankHook.framework/HankHook"
    • framework 的名稱注意去修改就行
    • 這樣的話 , 咱們作重簽名和代碼注入只須要 新建個空工程 運行 , 而後下載完微信的 ipa , 根目錄新建個 APP 文件夾 , 放進去運行便可.

dylib 代碼注入

有些工具作代碼注入的是 Library 就是 dylib 的庫 , 其實它的原理和咱們注入 framework 是同樣的 , 只不過步驟上略有不一樣.

咱們就使用 shell 簡單帶過一下.

另外 , iOS 如今已經不能添加 dylib,只能從 macOS 添加

工程準備

一樣是準備好已經重簽完的工程 或者上述 準備好了 shellipa 的工程 .

新建庫

File - New - TargetmacOS - Library , 我這裏取名 LBHookDylib

配置

  • 打開 Build Settings , 選擇 target , 找到 Base SDK , 選擇 iOS.
  • 找到 Code Sign Identity , 選擇 iOS 的證書
  • 選擇 Build Phases , 切換爲主工程的 target, 新建 Copy Files

  • 添加

  • Destination 選擇 Frameworks

  • shell 腳本中最後一行多加一句

    • yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/libLBHookDylib.dylib"
  • 運行 , 代碼注入成功 .

相關文章
相關標籤/搜索