1、先定一個小目標:修改查找好友功能
比如,我們想修改的功能是:在查找好友頁面,輸入特定字符串 (如: 0921),然後我們在請求發起之前,改成 “130 xxxx xxxx”,再去進行真實的好友手機號請求。別問我爲什麼hook這個功能,問就是玄學(某些教育類公司就給招生老師裝過有類似功能的wx)。
1.1 查找目標入口
通過XCode 自帶的View Capture,我們可以查看UI層級:順便根據類名,向要hook的目標類靠近。
首先看到的關鍵字,就是WCSearchController,貌似搜索邏輯是在這裏進行的吧?移步class-dump導出的頭文件,看看有沒有相關功能的函數:
然而,看完函數名很失望。。顯然wx的封裝程度,和代碼的優秀程度,不是那麼簡單的往VC裏堆疊邏輯,他們有着複雜的設計。不要緊,我們還有兩條線索:
1:查看其他VC:UI界面還有個VC叫AddFriendEntryViewController
2、猜測 函數名:搜索按鈕被點擊,應該有個searchButtonClicked: 類似的方法回調吧?
所以,兩條路都試一下:先看AddFriendVC,再在頭文件中全局搜searchButtonClicked關鍵字。
結果如下:
在這個VC裏,我們看到它引用了Class FindContact… 大致意思不就是:“查找聯繫人”嘛?先記住這個人。再去看關鍵字檢索:
哦吼~ 有點意思了,它實現了這個方法。
那我們就去好好看看 FindContactSearchViewCellInfo這個嫌疑類:
哇,在關鍵詞search的幫助下,我們很快就找到了一些獵物。
像CPU命中了cache一樣快樂,這個類裏實現了搜索按鈕點擊回調、有搜索命令的實現、有get搜索框文案的實現。
猜的這麼準,有什麼根據麼?有的,請看楊瀟玉的博客:如何在逆向工程中Hook得更準
(PS: 該同學很厲害。上學期間,自學iOS,反彙編分析很多代碼,runtime玩的相當6,其中蘋果開源的代碼故意隱藏掉一行很重要的函數調用,都被他發現了。後來拿到BAT所有offer,最終去了騰訊安全部門。然而他還是覺得自己當時(實習期間)向身邊神一樣的牛人們學到了很多東西。哦對了,他還是咱們逆向工具作者AloneMonkey的朋友,慢慢的你會發現,你讀的很多優秀博客,他們之間都有着不可告人 額不,是千絲萬縷的聯繫)
言歸正傳,我們hook一下這個類試試:
哦對,我們上篇文章提到用CaptainHook,作者的demo裏已經有使用方法和基本語法了。
xxxDylib.h 就是聲明hook類的地方
xxxDylib.m 就是寫你要hook方法的實現。
我們寫的hook代碼,最終被MonkeyDev打包成dylib,通過dyld動態鏈接完成之後,鏈接到了宿主app中。
驗證方法:(lldb) image list
命令 可以查看鏡像加載過程。
開始擼代碼:
doSearch方法的複寫:這裏可以打斷點調試,比如輸出一下參數什麼的
Hook完以後運行,點擊搜索按鈕,真的走到了這裏。證明了我們之前的所有猜測都是正確的,可以進行下一步嘗試了——分析代碼,修改代碼。
1.2 分析並改造目標功能
上篇提到的IDA反彙編工具,在這裏就派上了大用場。
查看doSearch僞代碼:
在僞代碼中,我們可以看到函數內部調用了:[r19 getSearchBarText]
。感覺這就是我們要修改的地方啊!
那麼我們就分析並重寫這個函數吧。該函數大致做了這麼幾件事:
- 創建SearchRequest
- 創建SKBuiltinString 用於初始化上面的Request,初始化參數是從
[self getSearchBarText]
得到的。 - 創建ProtobufCGIWrap(網絡請求包)
- 用之前的request初始化網絡請求包
- 創建Service
- 用Service創建一個Event,傳參是上面創建的CGIWrap和一個Flag(多次斷點,看到這個值永遠是69,猜測是用來區分event類型的枚舉)
- 最後一步,如果上面的Event創建成功,就添加監聽。入參是一個unsigned int類型的ListItem和一個id類型的Value。
以上這些僞代碼中方法名及參數類型,是在class-dump中找到的。
OK分析完了,利用objc/message 和runtime的一些工具,我們開始重寫doSearch。代碼如下:
Hook也Hook了,代碼也重寫了,那麼接下來就到了見證奇蹟的時刻——運行測試!
如果hook生效,那麼輸入框裏輸入"0921",就會搜所"wx_sunhonglei"(這裏大家可以換成搜自己的微信,畢竟這個微信名是我自己亂寫的,該用戶不存在)。
Cmd+R,wx起來後,進到添加好友頁面,
1、先輸入一個正常的微信號進行搜索測試,比如自己的微信號,bingo!邏輯走通了!證明我們重寫的doSearch方法是沒有問題的。
2、測試我們替換字符串的邏輯,輸入0921,看看能不能搜索到自己的微信。
結果。。。點擊搜索以後,界面沒有任何變化!甚至連代碼中的showLoading貌似也沒走!因爲沒看到loading的菊花。
百思不得其解!怎麼辦!!是我們doSearch方法寫的有問題嗎?!還是其他邏輯原因?
能不能看一下函數調用棧?
恭喜你,問到了逆向的精髓之處。在此之前,我被卡了兩星期。就是從這兒起,我開始沉下來學習了彙編原理和iOS的一些底層原理,最終越過山丘。
請繼續收看下兩集: 強大的斷點調試工具 & 符號表還原工具
。