iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

403同學發表於2019-10-17

Method Swizzle

利用OC的Runtime特性,動態改變SEL(方法編號)和IMP(方法實現)的對應關係,達到OC方法呼叫流程改變的目的。主要用於OC方法。

關於Runtime,如果大家不瞭解,可以看看Cooci老師的文章——iOS底層原理(二):Runtime研究(一),簡單瞭解一下。


在OC中,SEL 和 IMP 之間的關係,就好像一本書的“目錄”。

SEL 是方法編號,就像“標題”一樣。

IMP是方法實現的真實地址,就像“頁碼”一樣。

他們是一一對應的關係

SEL(標題)————————IMP(頁碼)

Runtime提供了交換兩個SEL和IMP對應關係的函式。通過函式交換、改變兩個SEL和IMP關係的技術,我們稱之為Method Swizzle(方法欺騙)。

多種Hook方式

  • class_addMethod
        •   利用AddMethod方式,讓原始方法可以被呼叫,不至於因為找不到SEL而崩潰
  • class_replaceMethod
         •   利用class_replaceMethod,直接給原始的方法替換IMP
  • method_setImplementation
         •   利用method_setImplementation,直接重新賦值原始的新的IMP

程式碼示例

一、註冊

之前我們有講過程式碼注入,本文不再過多贅述,需要的同學,點選iOS逆向——shell重簽名及程式碼注入跳轉。那麼上手直接擼程式碼啦。

1、新建專案,生成新的證書和描述檔案,在手機上跑一遍,保證描述檔案可以正確安裝到手機中。

2、執行Xcode,指令碼重籤APP

3、TARGETS建立Framework,並建立.h .m,這裡我們命名Inject

4、執行app, lldb動態除錯,分析程式碼邏輯。

5、如下圖所示,因為Xcode版本不同,有的Target 和 Action 會直接顯示類名,如果不直接顯示類名的,可以用po命令+物件地址看到ClassName。p是執行指令,o是object的意思。

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

6、找到相關名稱,就可以用class-dump這個工具把二進位制檔案所有的類的描述copy出來(相當於標頭檔案,但是不僅僅是標頭檔案)

class-dump -H 二進位制檔案 -o 目標資料夾複製程式碼

7、根據clas-dump匯出的檔案,考慮相關邏輯。關於檢視class-dump匯出的檔案,建議使用輕量級的sublime,使用更快速。

8、那麼接下來就是程式碼了。如下圖所示:

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

9、執行Xcode,重籤app,這裡要注意一點,上一章我寫的指令碼,在最後一行'#程式碼注入'是註釋狀態。那麼這次執行放開,才能注入成功。Framework的名字也要改成程式碼中對應的名字。

10、鐺鐺鐺鐺

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

二、登入

同理,登入的的業務邏輯我們要結合動態除錯(lldb)以及靜態分析(class-dump匯出的檔案)

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

  1. class-dump匯出檔案

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

2、根據檔案分析業務邏輯,找出相關類。先判定控制器,是WCAccountBaseViewController,通過找WCAccountBaseViewController的屬性,判斷WCAccountTextFieldItem *_textFieldUserPwdItem與密碼相關。

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

通過WCAccountTextFieldItem找其父類WCBaseTextFieldItem,

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

在WCBaseTextFieldItem下,查到WCUITextField *m_textField。以上僅是分析,但不能判斷是否就是我們需要的UITextField,所以首先,我們要lldb除錯。

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

3、lldb除錯如下

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

4、所以最終我們需要拿到textField,最後textField.text拿到pwd.

(1)方法交換

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

這是在inject類中增加新的方法,再實現方法交換,但WCAccountMainLoginViewController並不存在Maxy_onNext呼叫方法,要想真正的根據業務需求實現方法交換,需要給WCAccountMainLoginViewController增加新的方法,在inject實現方法交換。

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

這樣並不破壞wc的登入邏輯。關於引數type,請檢視官方文件,有明確的說明。

(2)方法替換

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

(3)setIMP和getIMP(推薦)

iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例

三種不同的方法,都能實現。最後推薦使用setIMP、getIMP。如果我哪裡寫的不對、不清楚,還希望你能指正出來,我們共同探討進步,如果你喜歡此文章,就動一動小手點個贊吧。



相關文章