因為朋友要求,所以今天來嘗試繞過某銀行 App 的越獄偵測。
一開始的步驟跟大部分的情況一樣,先破殼拿到未加密的 binary,然後 classdump Objective-C header,然後寫了 tweak 嘗試注入。不過這次事情沒這麼簡單… 經過一番折騰後,總算是破解了,因此寫下這次的思路,供以後參考用。
注意:本教學僅供個人研究以及個人使用,散佈破解過的 binary 在許多國家與地區是違法行為,請不要這樣做。
首先,寫完 tweak 之後,發現 tweak 的 NSLog 根本沒有出現,檢查了 tweak 本身跟 filter 也沒有發現任何問題。仔細看 console 裡面,發現沒有任何 dylib 注入成功的紀錄,甚至沒有啟動 App 的 log,這下可妙了。
接下來,用 MachOView 檢查,發現有趣的東西:
Google 一下,__RESTRICT 會阻止 binary 被 dylib 注入,所以這時候有三種思路解決:
- 破解 /usr/lib/dyld
- 替換 __RESTRICT
- 不要用 tweak 了,直接硬幹 binary
第一種方式的成本太高(我能力不足,加上不知道 dyld 跟 MobileSubstrate 的載入順序,還有亂改系統檔案的風險太高),所以不考慮,轉而考慮第二跟第三種方式,由於不管哪一個都會破壞 codesign 而導致需要重新簽名,所以就算做了 tweak 也不能放到 Cydia 散佈。而在本範例中,我們湊巧改 binary 的成本會比替換 __RESTRICT 低,所以採取第三種方式 — 硬幹 binary。
由於 mach-o binary 可以把多個 CPU 架構的 binary 合在一起,但是新架構的 CPU 向下相容舊架構的 binary,所以基於懶惰的關係,雖然目標 App 有 armv7、armv7s、arm64 三種架構,我們就只破解 armv7 就夠了。
lipo ./targetApp -extract armv7 -o ./targetApp_armv7
之後用 Hopper 或者 IDA Pro 來偷看一下:
經過強大的計算,我們可以得知這個 method 長這樣:
- (void)jailbreakStatus:(int)arg1 { if (arg1 < 1) { return; } [self jailbreakAction]; }
如果你要用 hook 的,當然就是把 arg1 給永遠弄成 0,不過我們今天是要 binary 破解,所以要顯示 hex
從這裡看出 cmp r2, 0x1
是 0x01 0x2a
,之後用任何 hex editor,把 0x00039e1e
改成 0x02 0x2a
,於是函式被我們改成了:
- (void)jailbreakStatus:(int)arg1 { if (arg1 < 2) { return; //arg1 永遠會是 0 或 1,所以下面的動作永遠不會被執行 } [self jailbreakAction]; }
然後就破解啦!最後把 binary 丟回去 IPA 重簽名就可以用了。
最後最後,一定要記得一點:
散佈破解過的 binary 在許多國家與地區是違法行為,請不要這樣做。
因此,無論你是把 __RESTRICT 拔掉,或者學我這樣直接破解,都不能散佈破解後的成果,只能供自己使用。