插件化之插件Service 新的Hook方法

本文同步自wing的地方酒館

給大家分享一個新的Hook插件Service的方法,與Activity替換類似,可以先在AndroidManifest.xml預留一個service,然後通過intent啓動,並且將真正的Service的classname傳遞過去。可是Service沒有涉及到Instrumentation更沒有Instrumentation.newService()方法,怎麼辦呢? 且聽我細細道來。

觀察Service的創建流程,發現我們只需要想辦法拿到intent即可做一些手腳。大家都知道,創建Service的時候,會走到H類裏:

他接收一個CreateServiceData類型的參數,恰好這個參數裏面有intent參數:

那麼能不能從這裏下手呢,答案是否定的。因爲data初始化的時候,並沒有將intent傳入,見下代碼:

所以我們換一種思路,bind的時候,有沒有intent呢?閱讀源碼得到以下信息:

哈哈,確實傳進來了。所以我們可以在bind的時候,拿到真正要啓動的classname,再bind的時候,把他給偷樑換柱! 具體怎麼做呢。H類是個Handler,觀察Handler內部有個callback,他可以在真正處理消息之前去做一些手腳,所以我們搞個callback給他幹進去。

新建一個callback ,在裏面把intent取出:

由於是基於bind的,所以要看一下之後做了什麼,觀察handleBindService方法,可以發現bind的時候service是已經創建好了的,並且存在一個名爲mService的ArrayMap裏。key爲token ,IBinder:

所以要做的事情就很明瞭了,他不是從這裏取嗎,那我們就給他替換掉呀,所以把mService取出來:

此時我擁有bind的msg裏面包含了intent、token等等信息,所以只要把對應key的value替換掉即可。在intent裏拿到真正的service class name,用classloader加載,此時service已經創建完畢了,但是還沒有初始化。

觀察系統service初始化過程,發現還需要context.setOuter attch等操作:

所以我們來手動模擬這個過程:

attach方法全部參數設置爲原本service自帶的參數。這裏只是改變了實例。初始化完畢之後,發現還需要進行binder通信

所以反射調用他,然後因爲是在bind的時候做的手腳,所以service丟失了onCreate()這個生命週期,所以手動調用他:

這樣就完成了Service的插件操作~~

歡迎加入我的Android酒館:425983695 討論技術~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章