Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 插件開發之360 DroidPlugin源碼分析(五)Service預注冊占坑

插件開發之360 DroidPlugin源碼分析(五)Service預注冊占坑

編輯:關於Android編程

在了解系統的activity,service,broadcastReceiver的啟動過程後,今天將分析下360 DroidPlugin是如何預注冊占坑的?本篇文章主要分析Service預注冊占坑,Service占了坑後又是什麼時候開始瞞天過海欺騙AMS的?先看下Agenda:

AndroidMainfest.xml中概覽 Service中關鍵方法被hook時機 startService被hook 瞞天過海流程圖 認識ServiceManager

AndroidMainfest.xml中概覽

這裡寫圖片描述vcq9xvS2rywgJm1kYXNoOy0gv8nNqLn9YWRiIHNoZWxsIHBzIL7Nv8nS1L+0tb3T0NK7uPa2wMGitcS9+LPMxvS2r8HLLjwvcD4NCjxwPs/uxL8gUGFja2FnZc6qIGNvbS5tb3Jnb28uZHJvaWRwbHVnaW4gLCCyosno1sMgYW5kcm9pZDpwcm9jZXNzPSZyZHF1bzs6UGx1Z2luUDAyJnJkcXVvOywgxMfDtEFwcNTL0NDKsSwgzai5/SBhZGIgc2hlbGwgcHMg" grep com.morgoo.droidplugin , 可以看到有兩個進程:

這裡寫圖片描述

startService被hook

IActivityManagerHookHandle.startService方法

這裡寫圖片描述

replaceFirstServiceIntentOfArgs()

這裡寫圖片描述

接下來我們繼續回到StartService類中,看下afterInvoke方法

這裡寫圖片描述

stopService,bindService,unbindService,setServiceForeground都是類似邏輯,可從源碼中證實。
在前一篇《插件開發之360 DroidPlugin源碼分析(四)Activity預注冊占坑》,我們曾了解到,8個進程中的service在預注冊占坑,在AndroidManifest.xml中只有一個,那如果插件要啟動多個service怎麼辦?這是第一個問題,而我們知道所有和服務相關的都要在系統的systemServer進程中進行注冊,難道DroidPlugin要逆天的本事?這是第二個問題
我們從代碼中發現有一個ServceManager,這和android系統中大管家ServiceManager相差一個i,難道要改大管家的職責?又多了一個疑惑
仔細看了下ServceManager中的代碼:

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

以上代碼可總結為:(以虛線分上下兩部分)
1.上部分主要是ServceManager單例及有一個handleXXX相關的方法,下部分主要是Service的一些生命周期方法。
2.我們基本可以確定之前問題2和問題3的答案了,沒有那麼逆天的本事來操作ServiceManager,也不能修改大管家ServiceManager的職責
3.那問題又來了,這個類到底是做啥的?還起一個叫ServceManager的名字,
以hanldeOnTaskRemoveOne方法為例看看:

這裡寫圖片描述

接著再看下ServceManager中的onBind方法:

這裡寫圖片描述

然後調到handleOnBindOne方法中,我們前面分析了一個handleOnTaskRemovedOne方法,下面1-7步驟套路都是一樣,主要在return時,直接調用service自身的onBind了,這和我們平時在Activity中new Intent,然後把這個intent傳到onBind中.

這裡寫圖片描述

那麼問題來了,還要這麼一個類倒騰來干啥呢?還記得上面有一處邏輯service為null時,就調用了handleCreateServiceOne,好戲在這裡:

這裡寫圖片描述
這裡寫圖片描述

看了上面的分析後,我們再去回想第一個問題,那如果插件要啟動多個service怎麼辦?不知道不沒有注意到mTokenServices,mNameService,mServiceTaskIds這些成員變量,它們都是Map,key不一樣,value全是Service,如個有多個service在插件中啟動了,mTokenServices,mNameService,mServiceTaskIds這些成員變量分別掌握了Service的Token,name,及任務id(通過token拿到的)。那豈不是已經在管理這些多個service了。至於附屬於這個類起的名字,叫什麼都無所謂。
以上可用如下流程圖表示:
這裡寫圖片描述

前面一直有個問題解釋的不徹底,就是問題3,ServceManager是否擔當了修改系統大管家ServiceManager的職責?接下來,我們就稍微了解下系統大管家ServiceManager是做什麼的?(PS: ServiceManager和Binder機制一樣,不是一天兩個就能研究的清楚的)

認識ServiceManager

Android系統Binder機制的總管是ServiceManager,所有的Server(System Server)都需要向它注冊,應用程序需要向其查詢相應的服務。平時,我們在studio上的DDMS中調試程序時,下圖這個就是ServiceManager

這裡以Java層加入ServiceManager及getService為數據流分析一下。

復習一下典型的Binder模式,有利於後面的理解:
1、客戶端通過某種方式得到服務器端的代理對象。從客戶端角度看來代理對象和他的本地對象沒有什麼差別。它可以像其他本地對象一樣調用其方法,訪問其變量。
2、客戶端通過調用服務器代理對象的方法向服務器端發送請求。
3、代理對象把用戶請求通過Android內核(Linux內核)的Binder驅動發送到服務器進程。
4、服務器進程處理用戶請求,並通過Android內核(Linux內核)的Binder驅動返回處理結果給客戶端的服務器代理對象。
5、客戶端收到服務器端的返回結果。

JAVA層代碼分析:
ServiceManager.java (frameworks\base\core\java\android\os)

對於xxxManager獲取服務端service基本如此用法:
舉例:
利用ContextImpl.java中的 public Object getSystemService(String name)

這裡寫圖片描述

然後再調用:ServiceManager.getService(ServiceName);獲取相應的服務端

這裡寫圖片描述

知道了客戶端獲取一個Service的方法之後,我們回到ServiceManager的服務端:

這裡寫圖片描述

BinderInternal.getContextObject() @ BinderInternal.java 是一個native 函數:

android_os_BinderInternal_getContextObject @ android_util_Binder.cpp
返回一個 BinderProxy對象保存到類成員mRemote(ServiceManagerProxy類成員)

public abstract class ServiceManagerNative extends Binder implements IServiceManager
ServiceManagerNative 繼承自 Binder 並實現了 IServiceManager 接口,利用 asInterface()則提供一個 ServiceManagerProxy 代理對象使用

class ServiceManagerProxy implements IServiceManager
定義了類ServiceManagerProxy(代理),ServiceManagerProxy繼承自IServiceManager,並實現了其聲明的操作函數,只會被ServiceManagerNative創建,它實現了IServiceManager的接口,IServiceManager提供了getService和addService兩個成員函數來管理系統中的Service。

這裡寫圖片描述

上面代碼總結如下:Java層先利用Parcel對象將數據進行序列化,然後利用transact將數據傳給binder驅動,就是上面mRemote.transact,mRemote在JNI層是一個叫BpBinder的對象:

JNI層代碼分析:
android_util_Binder.cpp

這裡寫圖片描述

每當我們利用BpBinder的transact()函數發起一次跨進程事務時,其內部其實是調用IPCThreadState對象的transact()。BpBinder的transact()代碼如下:

這裡寫圖片描述

到此,不再向下深究,具體想了解可以看Binder機制及IPC相關內容。
所以,到這把第2個問題徹底弄明白了,ServceManager和ServiceManager根本不是一回事。到次,Service的瞞天過海得以實現,接著,就是介紹時候說的那樣無需修改源碼,多進程,多service等功能。另外ContentProvider及BroadCast原理是類似,不再進行分析。
下篇將開始分析包管理(宿主插件和插件包名有什麼規則),APK解析(為什麼可以免安裝),進程管理(能確保隱藏起來,不會在process輕易被kill)

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved