[TOC]
iOS 逆向 -微信 helloWorld
一宇挫、 前言
本篇主要制作微信的 tweak,實現(xiàn)在非越獄版的手機上進行 hello World 彈窗吹泡,從而熟悉 iOS 逆向相關的工具(不包含lldb遠程調試骤星、反匯編技術等),以及了解 tweak 的主要流程(其實就是如何制作插件的過程)爆哑。
warn:本篇只是我在操作過程中的一點總結洞难,并不深入講解原理。若想深入了解可以查看iOS應用逆向工程 第2版或者看文章最后的參考文檔揭朝。
基本原理: 通過 app 啟動時調用我們注入的動態(tài)庫廊营,從而進行 hook 。而之所以能夠執(zhí)行我們注入的動態(tài)庫萝勤,是因為使用了
mobilesubstrate
這個庫露筒,這個庫能在程序運行的時候動態(tài)加載我們注入動態(tài)庫。而非越獄手機里面是沒有的敌卓,所以我們需要直接將這個庫打包進 ipa 中慎式,使用它的 API 實現(xiàn)注入。mobilesubstrate
庫在下面的 github 中有提供趟径,即是libsubstrate.dylib
.本demo的github地址 : TKDemo
其中 /others 提供了libsubstrate.dylib
與 本人寫的autoInsertDylib.sh
腳本瘪吏,autoInsertDylib.sh
是用來實現(xiàn)注入動態(tài)庫一體化。<p id = "p">以下部分工具(
例如 claa-dump 蜗巧、insert_dylib)可使用Xcode進行編譯(command + b)掌眠,然后在工程目錄下的Products中拷貝目標文件,放在/usr/local/bin
目錄中,方便在 Termimal 中使用幕屹。</p>主要流程: 砸殼 ==> 獲取ipa ==> 制作tweak ==> 查看(更改)依賴庫 ==> 注入動態(tài)庫 ==> 打包重簽名 ==> 安裝
二蓝丙、 正文
1. SSH 服務
實現(xiàn)在越獄手機上遠程進行ssh服務
OpenSSH 在 Cydia 中安裝 OpenSSH
- ssh : 遠程登錄
// 指令 ssh user@iOSIP
$ ssh mobile@192.168.1.6
- scp : 遠程拷貝
本地文件拷貝到iOS上(iOS拷貝到本地則相反)
// 指令 scp /path/to/localFile user@iOSIP:/path/to/remoteFile
scp ~/Desktop/1.png root@192.168.1.6:/var/tmp/
注意,OpenSSH 默認登錄密碼為 <a>alpine</a> 望拖,iOS 上的用戶只有 root 與 mobile渺尘,修改密碼使用passwd root(mobile)
2. 砸殼
用來在越獄手機上獲取ipa
PS:可直接使用PP助手下載越獄版本的 ipa 文件(我就是這么懶得)
- 下載并得到執(zhí)行文件
$ git clone https://github.com/KJCracks/Clutch
$ cd Clutch
// 使用 Xcode 進行build,得到可執(zhí)行文件
$ xcodebuild -project Clutch.xcodeproj -configuration Release ARCHS="armv7 armv7s arm64" build
- 將可執(zhí)行文件通過 ssh 拷貝到手機
scp Clutch/clutch root@<your.device.ip>:/usr/bin/
- 先 ssh 到越獄手機上,
clutch -i
列出當前安裝的應用,再使用clutch -d 序列號(或者bundle id)
進行砸殼
$ ssh root@<your.device.ip>
$ clutch -i // 列出當前安裝的應用
$ clutch -d bundle id (序列號) // 砸殼
clutch 將砸過后的 ipa 文件放到了/private/var/mobile/Documents/Dumped/
- 拷貝到桌面
$ scp root@<your.device.ip>:/private/var/mobile/Documents/Dumped/xx.ipa ~/Desktop
3. 導頭文件(查看 app 相關頭文件的信息)
dump 目標對象的 class 信息的工具。
將 demo.app 的頭文件導出到~/Document/headers/
中
class-dump -S -s -H demo.app -o ~/Document/headers/
4. 制作 dylib 動態(tài)庫
制作我們要注入的 dylib 動態(tài)庫
本文章使用的是 theos
PS:也可以使用iOSOpenDev
iOSOpenDev 集成在 Xcode 中澈灼,提供了一些模板凯旭,可直接使用 Xcode 進行開發(fā)。只是這個工具停止更新柔昼,對高版本的 Xcode 不能很好地支持狭握。本人裝了多次老是失敗堵幽,雖然最后在 Xcode 中有看到該工具拟淮,也不確定是否安裝成功干茉。若裝失敗可參考iOSOpenDev Wiki
4.1 安裝并配置 theos
從 github 下載至opt/theos/
brew install dpkg ldid
export THEOS=/opt/theos
sudo git clone --recursive https://github.com/theos/theos.git $THEOS
sudo chown -R $(id -u):$(id -g) /opt/theos
可<a>配置環(huán)境變量</a>,vi ~/.bash_profile
,在 <a>.bash_profile</a> 文件的最后加入(否則每次重啟Terminal都要重新export)
export PATH=/opt/theos/bin:$PATH
export THEOS=/opt/theos
4.2 創(chuàng)建tweak
使用 nic.pl
創(chuàng)建 tweak
若提示無此命令請根據(jù)上一步驟配置環(huán)境變量,或者不嫌麻煩使用/opt/theos/bin/nic.pl
根據(jù)提示選擇 <a>iphone/tweak</a>惩歉,接著分別輸入
- 項目名
- 該 deb 包的名字(
類似 bundle identifier, 此 bundle identifier 與要 hook 的 app 的 bundle identifier 不是同一個) - 作者
- tweak 作用對象的 bundle identifier(
比如微信為com.tencent.xin) - tweak 安裝完成后需要重啟的應用名。(
比如微信為WeChat)
如下所示:
完成后會看到四個文件(make 后將生成 .theos 俏蛮、obj 文件夾).
Makefile TKDemo.plist Tweak.xm control
- <a>Makefile</a> : 工程用到的文件撑蚌、框架、庫等信息搏屑。
該文件過于簡單争涌,還需要添加一些信息。如
指定處理器架構ARCHS = armv7 arm64
指定SDK版本TARGET = iphone:latest:8.0
導入所需的framework等等辣恋。
修改后的Makefile文件如下所示:
- <a>TKDemo.plist</a> 該文件中的 Bundles : 指定 bundle 為 tweak 的作用對象亮垫。也可添加多個 bundle, 指定多個為 tweak 作用對象。
- <a>control</a> : 該 tweak 所需的基本信息 (
其實大部分都是剛剛創(chuàng)建 tweak 所填寫的信息啦)
- <a>Tweak.xm</a>:重點文件伟骨,用來編寫 hook 代碼,因為支持
Logos
和C/C++
語法饮潦,可以讓我們不用去寫一些 runtime 方法(必要時候還是要寫)從而進行 hook 。
.x 文件支持Logos語法携狭,.xm 文件支持Logos和C/C++語法继蜡。
4.3 Logos 常用語法
-
%hook
指定需要 hook 的類,以%end
結尾逛腿。 -
%orig
在%hook
內部使用稀并,執(zhí)行 hook 住的方法原代碼。 -
%new
在%hook
的內部使用单默,給 class 添加新方法碘举,與class_addMethod
相同。
與 Category 中添加方法的區(qū)別:Category 為編譯時添加搁廓,class_addMethod
為動態(tài)添加引颈。
warn :添加的方法需要在 @interface 中進行聲明 -
%c
獲取一個類,等同于objc_getClass
境蜕、NSClassFromString
%hook
线欲、%log
、%orig
等都是mobilesubstrate
的MobileHooker
模塊提供的宏汽摹,除此之外還有%group
%init
李丰、%ctor
等,其實也就是把method swizzling
相關的方法封裝成了各種宏標記,若想深入了解逼泣,請左轉 Google
4.4 編寫 tweak.xm
熟悉各種語法之后便可以進行編寫代碼了趴泌,其中MMUIViewController
為微信的基礎的ViewController舟舒。我們通過 hook viewDidApper:
來進行 hello World 彈窗。
4.5 編譯
使用make
進行編譯
若想重新編譯記得先make clean
make
后在當前文件夾下面將生成兩個文件夾:.theos
與 obj
,其中我們編譯完成的動態(tài)庫就在.thoes/obj/debug
的下面嗜憔,與工程名相同秃励。
若編譯的時候提示找不到 common.mk
或者是 tweak.mk
,請根據(jù)上述步驟(<a>4.1 安裝并配置 theos</a>)重新 export theos吉捶,或寫入至~/.bash_profile夺鲜,或更改Makefile的文件,將$(THEOS)/makefiles
與 $(THEOS_MAKE_PATH)
替換成opt/theos/makefiles
5. 查看(修改)依賴
5.1 otool
查看執(zhí)行文件所依賴的庫文件
otool -L TKDemo.dylib
若發(fā)現(xiàn)有依賴 /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate
使用 install_name_tool 更改依賴呐舔。
CydiaSubstrate 只有越獄的手機上才有币励,因此需要我們手動更改并導入。
5.2 更換動態(tài)庫的依賴
install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/libsubstrate.dylib tkchat.dylib
// install_name_tool -change 需要替換的庫 @loader_path/需要引用的庫 需要更改的dylib
6. 動態(tài)庫注入
把我們寫的動態(tài)庫注入到要 hook 的二進制文件
先將 ipa 文件解壓珊拼,在解壓后的/Payload
目錄中食呻,將app可執(zhí)行文件拷貝出來。再將我們編寫的動態(tài)庫與libsubstrate.dylib 拷貝至app的包內容中澎现。
執(zhí)行命令:
./insert_dylib 動態(tài)庫路徑 目標二進制文件
./insert_dylib @executable_path/xxxx.dylib xxxx
// @executable_path 是一個環(huán)境變量仅胞,指的是二進制文件所在的路徑
注入成功后將app目錄中的 WeChat 刪除,將 WeChat_patched 改為WeChat剑辫。
warn :使用 insert_dylib 時若出現(xiàn) error 記得修改權限干旧, chmod 777 insert_dylib
7. 打包、重簽名妹蔽、安裝
使用圖形化打包簽名工具 ios-app-signer
選擇相應的證書與 Provisioning Profile 文件進行打包莱革。
友情提示:如果證書沒有支持 watch,請刪除 app 中的<a>watch</a>相關的文件讹开。
證書的話可以用 Xcode 新建個 Project (個人開發(fā)者證書7天后過期)盅视,在手機上運行下即可生成。導入時記得到真機上需要有相應的Provisioning Profile 文件旦万∧只鳎可在 Xcode-Window-Devices,雙指點擊設備查看Provisioning Profile文件成艘,點擊下面的 +
進行安裝赏半。
也可使用PP助手進行安裝。
8. hello World
最后就是我們的 hello World
9. autoInsertDylib.sh 腳本
由于以上的操作(查看更改依賴庫淆两、注入動態(tài)庫)都類似且繁瑣断箫,個人懶癌,就寫了這個sh秋冰。
<a>warn !!!</a>
<a>warn !!!</a>
<a>warn !!!</a>
該腳本的中insert_dylib
路徑使用的是/usr/local/bin
(請看前言),請根據(jù)自身環(huán)境更改腳本中的insert_dylib
路徑仲义,以免錯誤。
iOS App Singer
本人放在了/Applications/
中,若Applications中沒有埃撵,則在腳本執(zhí)行完手動打開赵颅。
使用:
./autoInsertDylib.sh ipa路徑 libsubstrate.dylib路徑 要注入的dylib路徑
autoInsertDylib.sh 內容
# !/bin/bash
SOURCEIPA="$1"
LIBSUBSTRATE="$2"
DYLIB="$3"
if [ ! -d ~/Desktop/tk-tweak-temp-folder/ ]; then
echo "在 Desktop 創(chuàng)建tk-tweak-temp-folder"
mkdir ~/Desktop/tk-tweak-temp-folder
else
rm -rf ~/Desktop/tk-tweak-temp-folder/*
fi
cp "$SOURCEIPA" "$DYLIB" "$LIBSUBSTRATE" ~/Desktop/tk-tweak-temp-folder/
echo "正將" ${SOURCEIPA##*/} ${DYLIB##*/} ${LIBSUBSTRATE##*/} "拷貝至~/Desktop/tk-tweak-temp-folder"
cd ~/Desktop/tk-tweak-temp-folder/
otool -L ${DYLIB##*/} > depend.log
grep "/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate" depend.log >grep_result.log
if [ $? -eq 0 ]; then
echo "發(fā)現(xiàn)有依賴于 CydiaSubstrate, 正將其替換為 libsubstrate"
install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/libsubstrate.dylib ${DYLIB##*/}
else
echo "沒有發(fā)現(xiàn)依賴于CydiaSubstrate"
fi
echo "解壓" ${SOURCEIPA##*/}
unzip -qo "$SOURCEIPA" -d extracted
APPLICATION=$(ls extracted/Payload/)
cp -R ~/Desktop/tk-tweak-temp-folder/extracted/Payload/$APPLICATION ~/Desktop/tk-tweak-temp-folder/
echo "注入" ${DYLIB##*/} "到" $APPLICATION
cp ${DYLIB##*/} ${LIBSUBSTRATE##*/} $APPLICATION/
echo "刪除" ${APPLICATION##*/} "中 watch 相關文件"
rm -rf ~/Desktop/tk-tweak-temp-folder/$APPLICATION/*watch*
rm -rf ~/Desktop/tk-tweak-temp-folder/$APPLICATION/*Watch*
echo "是否注入" ${DYLIB##*/} ":(Y/N)"
insert_dylib @executable_path/${DYLIB##*/} $APPLICATION/${APPLICATION%.*} > insert_dylib.log
echo "注入成功"
cd $APPLICATION
rm -rf ${APPLICATION%.*}
mv ${APPLICATION%.*}_patched ${APPLICATION%.*}
echo "正將" ${APPLICATION%.*}_patched "覆蓋為" ${APPLICATION%.*}
cd ~/Desktop/tk-tweak-temp-folder/
echo "刪除臨時文件"
rm -rf ${SOURCEIPA##*/} ${DYLIB##*/} ${LIBSUBSTRATE##*/} extracted insert_dylib.log depend.log grep_result.log
echo "打開 tk-tweak-temp-folder 文件夾"
open ~/Desktop/tk-tweak-temp-folder
open /Applications/iOS\ App\ Signer.app
三、 總結
以上就是整個 iOS 逆向的主要流程(雖然hook的代碼很渣),其中注入動態(tài)庫與打包重簽名的工具不止一種暂刘,可以根據(jù)自己的愛好網(wǎng)上查找饺谬。本人也是踩了不少坑不斷摸索來的,比如由于tweak工程名的問題谣拣,導致使用 iOS App Signer
打包重簽名的一直error:<a>
Error verifying code signature</a>募寨。希望能給剛入iOS 逆向坑的人一點幫助,文章中如有錯誤歡迎指出森缠。由于涉及只是工具的使用拔鹰,涉及到的原理比較薄弱,若想深入了解可以去閱讀下參考文檔辅鲸。