溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

發(fā)布時間:2020-07-02 11:04:30 來源:網(wǎng)絡(luò) 閱讀:3578 作者:永恒之黑 欄目:移動開發(fā)

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

開篇


通過本文你能了解 iOS 逆向的基本知識,對 iOS App 的安全有一定了解。然后能舉一反三,在自家 App 找到危險漏洞加以預(yù)防,保證用戶數(shù)據(jù)安全。

在安全領(lǐng)域,攻與防永遠存在。哪怕是 iPhone 有著強大的安全防護機制,也擋不住那些極客們一次又一次的好奇,開發(fā)了很多強大且便利的工具。本文就是在這些極客們提供的工具的基礎(chǔ)上完成的!

準(zhǔn)備工具


  • Mac 電腦和越獄 iPhone 手機
  • 查看手機系統(tǒng)目錄工具 iFunbox 或 iTools
  • 網(wǎng)絡(luò)分析工具 Charles
  • 反編譯工具 Hopper, IDA Pro
  • 查看頭文件工具 class-dump
  • 砸殼工具 dumpdecrypted, Clutch
  • 調(diào)試器 lldb 或 gdb
  • 調(diào)試工具:Cycript

HTTP(S) 抓包


HTTP 抓包
第一步:獲取 MAC IP

按下Option鍵,同時點擊 Mac 菜單欄上的無線網(wǎng) Icon,能看到當(dāng)前電腦的 IP 地址。
或在終端輸入 ifconfig en0 也可查看。

第二步:設(shè)置代理

保證手機和電腦在同一 WIFI 下,在手機上,點擊“設(shè)置->無線局域網(wǎng)->連接的WiFi”,設(shè)置HTTP代理:

服務(wù)器:為 Mac 電腦 IP 地址(如192.168.1.122)

端口:8888

第三步:抓包

在電腦端,打開 Charles。使手機發(fā)生網(wǎng)絡(luò)請求,Charles 會彈出一個詢問的對話框

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

點擊“Allow”允許,Charles 會出現(xiàn)手機的 HTTP 請求記錄列表。

HTTPS 抓包
第一步: 獲取證書安裝地址

安裝 SSL 證書到手機設(shè)備。點擊 Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Device

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

出現(xiàn)彈窗得到地址 chls.pro/ssl

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

第二步:iPhone 安裝證書

在手機 Safari 瀏覽器輸入地址 chls.pro/ssl,出現(xiàn)證書安裝頁面,點擊安裝,手機設(shè)置有密碼的輸入密碼進行安裝

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

第三步:配置代理 host

Charles 設(shè)置 Proxy。選擇 Proxy -> SSL Proxying Settings...

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

勾選 Enable SSL Proxying,點擊 Add

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

Host 設(shè)置要抓取的 HTTPS 接口,Port 填寫 443。

讓手機重新發(fā)送 HTTPS 請求,可看到抓包。

<b> 注意:不抓包請關(guān)閉手機 HTTP 代理,否則斷開與電腦連接后會連不上網(wǎng)! </b>

拿到 .h 頭文件

從 AppStore 直接下載的 ipa, 蘋果公司對其做了 FairPlay DRM 技術(shù)進行加密保護,無法直接使用 class-dump 工具獲取頭文件。但是如果是通過 development 打包出來的話的 App 的話,是可以直接使用 class-dump 查看所有頭文件的,此部分介紹就是通過此情況來說明如何獲取 .h 文件的。

此處不再介紹 class-dump 工具的安裝過程,具體步驟請直接百度。

進入到 appName.ipa 所在目錄,修改擴展名為 .zip,然后解壓文件,得到 appName.app。

然后執(zhí)行:

class-dump -H appName.app -o ./headers/

命令執(zhí)行完成后,會在當(dāng)前目錄下的 headers 目錄里看到 app 所有頭文件。

如果添加參數(shù) -A -S 會在頭文件里標(biāo)記處類方法和屬性的 IMP 地址(模塊偏移前基地址)。

class-dump -H -A -S appName.app -o ./headers/

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

SSH 訪問手機文件目錄


在你的越獄手機上使用 Cydia 應(yīng)用市場安裝 OpenSSH,并保證 Mac 和 iPhone 處于同一個WIFI下,在 MAC 終端輸入:

ssh root@IP ,IP 替換為 iPhone 的 IP 地址

輸入默認密碼:alpine

即可進入 iPhone 終端。

使用 Clutch 反編譯 App


第一步:重新簽名 debugserver

取得 debugserver 有兩種方式。

第一種是在 Mac 電腦中拿到

進入路徑 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/8.3/DeveloperDiskImage.dmg(其中路徑里 8.3,代表 iOS 系統(tǒng)版本,需與準(zhǔn)備的越獄手機系統(tǒng)版本保持一致)。雙擊 DeveloperDiskImage.dmg,將目錄里的 usr/bin/debugserver 復(fù)制到指定文件夾中。

第二種是在越獄手機里拿到

如果手機連接過手機并通過 XCode 調(diào)試過 app,會在手機里的 /Developer/usr/bin/ 目錄下生成一個 debugserver 文件。通過 iFunbox 導(dǎo)出至 Mac 桌面?;蚴褂?scp 命令 cpoy 出來。

重簽名 debugserver

即給 debugserver 添加 task_for_pid 權(quán)限

創(chuàng)建 entitlements.plist,添加如下四個 key:

com.apple.springboard.debugapplications

get-task-allow

task_for_pid-allow

run-unsigned-code

key 對應(yīng)的 value 都設(shè)為設(shè)為 ture

將 entitlements.plist 和 debugserver 放在同一個目錄下,執(zhí)行以下命令:

codesign -s - --entitlements entitlements.plist -f debugserver

此命令會重新簽名 debugserver,將簽名后的 debugserver 拷貝至手機系統(tǒng)的 /usr/bin/ 目錄下。

<b>注意:不要將 debugserver 拷貝至 /Developer/usr/bin/ 路徑下</b>

第二步: 通過 Clutch 拿到反編譯后的 App 可執(zhí)行文件

將下載好的 Clutch 放入手機的 /usr/bin/ 路徑下。然后,給 Clutch 賦予權(quán)限,通過 SSH 登錄到手機,進入 /usr/bin/ 執(zhí)行 chmod a+x ./Clutch。

通過命令 Clutch -i,列出所有的可被 Clutch 的應(yīng)用。

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

對指定序號的應(yīng)用進行脫殼,如企業(yè)微信,序號是1,命令是 Clutch -d 1。執(zhí)行完成后,會得到脫殼后的 ipa。

第三步:使用 class-dump 拿到 .h 頭文件

使用上文 <b>【拿到.h頭文件】</b> 介紹的方法拿到脫殼后的 App 頭文件和并記下要打斷點的方法的 IMP 地址。

動態(tài)調(diào)試 App

本文動態(tài)調(diào)試用到的調(diào)試器是 lldb。

第一步:使 iPhone 進入等待掛載狀態(tài)

SSH 登錄到手機,執(zhí)行 ps -e 命令得到 App PID 或項目名稱。

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

進入 /usr/bin/ 執(zhí)行 ./debugserver IP:port -a PID|appProjectName。 其中第一個參數(shù) IP 可以替換為 Mac 電腦 IP地址,或者使用 * 通配符,允許所有 IP 調(diào)試;第二個參數(shù) port 隨便寫一個就行。第四個參數(shù) 可以指定要調(diào)試 App 的 PID 或項目名稱。比如要調(diào)試的 PID 為 6019 的搜狗輸入法項目名稱為SogouInput,則命令即為:

./debugserver *:1234 -a 6019./debugserver *:1234 -a ‘SogouInput’

此命令執(zhí)行完成后,app會進入等到掛載狀態(tài),app會被卡住點擊無反應(yīng)。正?,F(xiàn)象!

如果此命令報錯,如出現(xiàn) Segmentation fault: 11 等情況,說明 App 做了反動態(tài)調(diào)試保護。遇到此種情況,需先確定 App 采用了哪種保護方案,然后進一步找到對應(yīng)措施,干掉它的反動態(tài)調(diào)試保護。

第二步:監(jiān)聽進程,進入掛載狀態(tài)

重新打開一個 Mac 終端執(zhí)行 lldb 進入 lldb 調(diào)試狀態(tài)。然后輸入

process connect connect://iPhoneIP:port

iPhoneIP 替換為 iPhone 的 IP 地址;port 改為剛才指定的端口,即 1234。

待命令執(zhí)行完成后,App 即進入掛載狀態(tài)。

第三步:獲取 App 的 ASLR 偏移量

ASLR偏移量其實就是虛擬內(nèi)存的地址相對于模塊基地址的偏移量。有兩個概念需要熟悉一下:

  • 模塊在內(nèi)存中的起始地址 ---- 模塊基地址
  • ASLR偏移 ---- 虛擬內(nèi)存起始地址與模塊基地址的偏移量

在 lldb 調(diào)試器模式下,執(zhí)行 imge list -o -f

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

模塊偏移后的基地址 = ASLR 偏移量 + 模塊偏移前基地址(方法的 IMP 地址)

上面這個公式是尤為重要的,因為 Class-dump 中顯示的都是“模塊偏移前基地址”,而 lldb 要操作的都是“模塊偏移后的基地址”。所以從 Class-dump 到 lldb 要做一個地址偏移量的轉(zhuǎn)換。

至此,已得到了 App 的 ASLR 偏移量和方法的 IMP 地址。

第四步:打斷點,調(diào)試

在 lldb 模式下執(zhí)行,br s -a 'ASLR 偏移量+ IMP',然后執(zhí)行 c,使 App 跑起來,觸發(fā)一個方法調(diào)用,就會進入斷點模式。輸入 po $arg1 打印第一個參數(shù)。

然后,配合著抓包工具 Charles(比如分析網(wǎng)絡(luò)請求加密邏輯) 和 Class-dump(比如修改某個類的方法返回值)等工具,你就可以隨意動態(tài)調(diào)試 App 了,就像在 XCode 里調(diào)試一樣!

<b>br 命令說明</b>

br dis 1 -- 禁用(disable)編號為1的斷點

br en 1 -- 啟用(enable)編號為1的斷點

br dis -- 禁用所有斷點

br en -- 啟用所有斷點

br del 1 -- 刪除(delete)編號為1的斷點

br del -- 刪除所有斷點

br list -- 列出所有斷點

使用 dumpdecrypted 破殼 App


dumpdecrypted 脫殼工具的原理是:將應(yīng)用程序運行起來(iOS 系統(tǒng)會先解密程序再啟動),然后將內(nèi)存中的解密結(jié)果 dump 寫入文件中,得到一個新的可執(zhí)行程序。

第一步:生成 .dylib 文件

在終端進入到下載后的目錄中,cd dumpdecrypted-master,然后執(zhí)行 make,即可生成 dumpdecrypted.dylib

第二步:找到 App 的 Documents 文件夾路徑

通過 SSH 登錄到 iPhone,然后執(zhí)行 ps -e 查看進程,獲取要破殼的進程 PID。然后執(zhí)行 cycript -p PID 附加到 PID 進程上。最后執(zhí)行 [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]得到 Documents 文件夾路徑。

第三步:開始破殼

將第一步生成的 dumpdecrypted.dylib 拷貝到第二步得到的 .../Documents/ 路徑下,命令如下:
scp ~/dumpdecrypted.dylib root@IP:/var/mobile/Containers/Data/Application/2B4C6281-C015-4FF3-A8EC-5E5C7554D447/Documents(將路徑里的 UDID 替換為你的要破殼的 App 的 UDID)

進入 Documents 目錄下,執(zhí)行DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/<br/>Application/BFED82A3-3238-4F41-B797-C1CB584CBE05/appProjectName.app/appProjectName(將路徑里的 UDID 替換為你的要破殼的 App 的 UDID;將 appProjectName 替換為要破殼 App 的項目名稱)

待命令執(zhí)行完,會在當(dāng)前目錄生成一個名為 appProject.decrypted 的文件,這個就是破殼后的 App 可執(zhí)行文件,要的就是它!使用 Class-dump 即可得到頭文件?;蚴褂?Hopper 或 IDA Pro 進行反編譯。

給你的 App 添加反動態(tài)調(diào)試機制


ptrace

為了方便應(yīng)用軟件的開發(fā)和調(diào)試,從Unix的早期版本開始就提供了一種對運行中的進程進行跟蹤和控制的手段,那就是系統(tǒng)調(diào)用 ptrace()。
通過 ptrace 可以對另一個進程實現(xiàn)調(diào)試跟蹤,同時 ptrace 還提供了一個非常有用的參數(shù)那就是 PT_DENY_ATTACH,這個參數(shù)用來告訴系統(tǒng),阻止調(diào)試器依附。

所以最常用的反調(diào)試方案就是通過調(diào)用ptrace來實現(xiàn)反調(diào)試。

sysctl

當(dāng)一個進程被調(diào)試的時候,該進程會有一個標(biāo)記來標(biāo)記自己正在被調(diào)試,所以可以通過 sysctl 去查看當(dāng)前進程的信息,看有沒有這個標(biāo)記位即可檢查當(dāng)前調(diào)試狀態(tài)。

檢測到調(diào)試器就退出,或者制造崩潰,或者隱藏工程,當(dāng)然也可以定時去查看有沒有這個標(biāo)記。

syscall

為從實現(xiàn)從用戶態(tài)切換到內(nèi)核態(tài),系統(tǒng)提供了一個系統(tǒng)調(diào)用函數(shù) syscall,上面講到的 ptrace 也是通過系統(tǒng)調(diào)用去實現(xiàn)的。

在Kernel Syscalls27這里可以找到 ptrace 對應(yīng)的編號。

26. ptrace 801e812c T

所以如下的調(diào)用等同于調(diào)用 ptrace:

syscall(26,31,0,0,0);

<b> arm </b>

syscall 是通過軟中斷來實現(xiàn)從用戶態(tài)到內(nèi)核態(tài),也可以通過匯編 svc 調(diào)用來實現(xiàn)。

覺得不錯的話,歡迎關(guān)注我的公眾號哦!

教你如何動態(tài)調(diào)試 iOS App(反編譯App)

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI