當我們要逆向第三方應用時,首先就是要將應用安裝在我們的手機上,然後進行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腳本,請先花點時間看下入門教程。
-
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