shell腳本實現iOS包重簽名及代碼注入

當我們要逆向第三方應用時,首先就是要將應用安裝在我們的手機上,然後進行hook分析,找到對應的方法調用,進行代碼注入,破解其正常流程,從而達到逆向目的。接下來將詳細講解分析該過程具體實現。

一、shell腳本實現重簽名

1. 我們以最常見的應用微信爲例,其他應用原理一樣!首先我們去PP助手下載越獄版本的微信應用,如下圖:

01

  • 1.1 越獄版本的應用是沒有加密的,正式版本的應用是加過密的,我們用MachOView來查看應用的可執行文件信息,演示如下:

     

    02

  • 1.2 從上圖中我們可以看到LC_ENCRYPTION_INFO_64加密信息這一欄中的Crypt ID爲0,代表沒有加密,而微信的正式版本此處爲1,代表用到了某一種加密方式,加密的我們是很難去進行代碼注入的。

2.我們先來看一下重籤微信app的效果,演示如下:

03

  • 2.1 接下來我們將詳細講解重簽過程,這裏的重籤可以手動也可以使用腳本,手動比較繁瑣,這裏就不演示了。下面我們基於shell腳本來完成代碼的重新簽名,總計不超過20條命令,在進行shell腳本講解之前,如果你不熟悉shell腳本,請先花點時間看下入門教程

  •  

     

    2.2 我們新建立一個WeChat的同名工程,方便後續文件的替換,其他應用類似。然後在工程目錄下新建一個APP文件,這裏用於放置我們剛下載的ipa包,演示如下:

    04

  • 2.3 我們爲工程創建一個腳本文件,然後添加證書管理,接下來運行即可,三步就解決了重簽名問題,演示如下:

     

    05

  • 2.4 關鍵就在於shell腳本的實現過程,這裏給出shell簽名腳本,腳本中每一行都做了詳細註釋,完整腳本地址

 

 

#獲取手動創建的APP文件夾,用來放置越獄版本的Ipa包,${SRCROOT} 代表工程文件所在的目錄
crackPath="${SRCROOT}/APP"
#獲取越獄版本Ipa路徑
oldIpaPath="${crackPath}/*.ipa"
# 創建一個臨時文件夾,用來放置解壓的Ipa文件
tempPath="${SRCROOT}/Temp"

#首先先清空Temp文件夾
rm -rf "$tempPath"
#創建臨時文件夾目錄
mkdir -p "$tempPath"


# 1. 解壓IPA到temp下
unzip -oqq "$oldIpaPath" -d "$tempPath"
# 拿到解壓的臨時的APP的路徑
oldIPaPath=$(set -- "$tempPath/Payload/"*.app;echo "$1")

# 2. 將解壓出來的.app拷貝進入工程下
# BUILT_PRODUCTS_DIR 工程生成的APP包的路徑(系統創建的)
# TARGET_NAME target名稱(系統創建的)
targetAppPath="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
# 打印app編譯後的路徑
echo "app路徑:$targetAppPath"

#先刪除app所在路徑文件
rm -rf "$targetAppPath"
#重新創建該文件路徑
mkdir -p "$targetAppPath"
#將解壓的app文件拷貝到Xcode編譯的app文件目錄,讓Xcode認爲這是它編譯出來的,Xcode就會幫我們完成簽名工作
cp -rf "$oldIPaPath/" "$targetAppPath"


# 3. 刪除extension和WatchAPP.個人證書沒法簽名Extention
rm -rf "$targetAppPath/PlugIns"
rm -rf "$targetAppPath/Watch"


# 4. 更新info.plist文件 CFBundleIdentifier,PlistBuddy是更改plist文件的可執行文件
#  設置:"Set : KEY Value" "目標文件路徑"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$targetAppPath/Info.plist"


# 5. 重簽名第三方 FrameWorks
tagetAppFramworkPath="$targetAppPath/Frameworks"
if [ -d "$tagetAppFramworkPath" ];
then
for frameWork in "$tagetAppFramworkPath/"*
do

#簽名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$frameWork"
done
fi

二、framework代碼注入

1. 首先我們在代碼簽名的工程的基礎上,創建一個framework庫,並添加一個load方法,裏面寫入我們需要注入的代碼,演示如下:

06

  • 1.1 然後我們在腳本後面增加註入代碼
# 拿到MachO文件的路徑
APP_BINARY=`plutil -convert xml1 -o - $targetAppPath/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
#注入
yololib "$targetAppPath/$APP_BINARY" "Frameworks/Inject.framework/Inject"
  • 1.2 運行工程,可以看到我們注入的代碼成功了,演示如下:

     

    07

  • 1.3 上面工程有306個報錯,這個是我電腦權限的問題,可以忽略,你的電腦運行應該不會有問題。我們可以看到代碼已經注入成功,至於爲什麼是在load方法中添加,詳細瞭解請查看我的另一篇文章《dyld加載應用啓動原理詳解》,裏面有分析代碼的注入時機!

  • 1.4 接下來我們來分析yololib這句腳本到底幹了什麼?首先我們將自己創建的framework可執行文件和wechat的可執行文件拿出來,然後執行yololib命令演示如下圖:

     

    08

  • 1.5 yololib下載地址。使用yololib將自己的framework注入到WeChat可執行文件中,演示如下圖:

    09

     

  • 1.6 接着用machOView來查看WeChat可執行文件中是否存在自己創建的庫問題,如下圖:

     

    10

2. 截獲微信註冊方法

  • 2.1 我們使用調試工具查看註冊按鈕的調用方法,演示如下圖:

     

    11

  • 2.2 我們可以看到調用的Target是"WCAccountLoginControlLogic",點擊註冊按鈕執行的方法爲"onFirstViewRegester",有了這個,接下來就是簡單的方法交換了。

  • 2.3 我們在自己的framwork中寫入方法交換方法,如下:

+(void)load
    {
        Method oldMethod = class_getInstanceMethod(objc_getClass("WCAccountLoginControlLogic"), @selector(onFirstViewRegester));
        
        Method newMethod = class_getInstanceMethod(self, @selector(test));
        
        method_exchangeImplementations(oldMethod, newMethod);
    }
    
-(void)test{
    NSLog(@"----截獲到微信註冊按鈕點擊------");
}
  • 2.4 接下來我們運行程序,點擊按鈕,演示如下:

     

    12

到此,shell腳本的自動簽名和framework代碼注入到此完成,還有一種dylib的注入,是用macOS的庫來完成的,相對來說這個比較簡單,如果有需要我會更新dylib的相關文章,主要熟悉掌握framwork的注入即可。附上腳本下載,幫助到你請給一個Star


作者:Qinz
鏈接:https://www.jianshu.com/p/7d5daf6436b2

發佈了50 篇原創文章 · 獲贊 13 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章