socket介紹
? ? ? ? socket是系統(tǒng)提供用于網(wǎng)絡(luò)通信的方法喉酌,它并不是一個協(xié)議但是很多協(xié)議間的通信數(shù)據(jù)是通過socket中方法來傳遞數(shù)據(jù)的愤兵,目前在APP中用的最多就是即時通訊和直播,這兩年比較火的直播的音視頻數(shù)據(jù)就是通過socket傳遞的鹿霸,有RTMP協(xié)議和Http-flv協(xié)議,如果有想了解這兩個協(xié)議的可以在下面留言秆乳,之后我會介紹如何進(jìn)行直播監(jiān)控使用代碼解析這兩個協(xié)議懦鼠,這篇文章主要介紹socket監(jiān)控實現(xiàn)钻哩。
? ? ? ? 在iOS中socket有兩種,一種是c層的socket.h中純C的寫法肛冶,還有就是CFNetwork中的CFSocket,這兩種方式在iOS中可以雜在一起使用導(dǎo)致socket創(chuàng)建的方式有很多種街氢。
socket監(jiān)控
? ? ? ? 其實監(jiān)控原理都是大同小異的都會使用hook機(jī)制,運行時動態(tài)替換將原方法替換成一個新方法睦袖,參數(shù)和原來方法相同珊肃,AOP編程和swizzle就是普通的hook,接下來介紹的就是不同于這兩種機(jī)制的hook馅笙。 ? ? ? ?
? ? ? ? 對于C方法的監(jiān)控我們需要借助于facebook提供的一個工具fishhook伦乔,fishhook的實現(xiàn)是利用iOS中Mach-o的編譯原理,使用內(nèi)存地址的偏移來替換原有的方法,至于如何實現(xiàn)的這里就不講了董习,網(wǎng)上有很多資料特別是iOS安全攻防中講的特別詳細(xì)烈和,我們這里來說說如何使用。
首先我們需要定義一下靜態(tài)方法皿淋,靜態(tài)方法的參數(shù)和你需要監(jiān)控方法參數(shù)一樣招刹。
再定義一個開關(guān)方法open,然后使用fishhook提供的rebind_symbols函數(shù)進(jìn)行hook沥匈,替換成一想要實現(xiàn)功能的方法,open這個方法可以在appdelegate的didFinishLaunchingWithOption中調(diào)用蔗喂,實現(xiàn)全局監(jiān)控。
? ? ? ? 最后在這個函數(shù)中高帖,有返回值的你需要將返回值return回調(diào)回去缰儿,connect方法的返回值是int值,需要用靜態(tài)方法傳遞參數(shù)獲取返回值回調(diào)散址。這中和AOP切面編程還有swizzle一樣了乖阵,只是上面的實現(xiàn)步驟不一樣,最后你就可以在my_connect中實現(xiàn)你想要做的事预麸,獲取IP瞪浸、端口號、鏈接錯誤等等吏祸,當(dāng)然不止這些对蒲,一些協(xié)議層的數(shù)據(jù)分析也可以通過這些方法來監(jiān)控,至少這樣就能做到socket的監(jiān)控了贡翘。
說了這么多蹈矮,不了解使用的小伙伴可能還是不清楚,我寫了個demo,我把github代碼鏈接發(fā)在這里,覺得對你有用的話請給個星星鸣驱。
https://github.com/LonelyWise/SocketMonitor.git
? ? ? ?運行的時候最好使用真機(jī)泛鸟,原因是在模擬器上網(wǎng)絡(luò)請求會走socket就會導(dǎo)致模糊,但是在真機(jī)上蘋果系統(tǒng)就會將系統(tǒng)的和網(wǎng)絡(luò)請求的給屏蔽了踊东,不主動調(diào)用就不會運行到socket北滥。
如果有對直播協(xié)議感興趣的的可以私聊我刚操,我接下來會寫一下關(guān)于RTMP和http-flv協(xié)議層數(shù)據(jù)的解析,也是基于本篇文章socket監(jiān)控的基礎(chǔ)再芋,對APM有興趣的也可以私聊我菊霜,一起探討。