插件開(kāi)發(fā)之360 DroidPlugin源碼分析(四)Activity預(yù)注冊(cè)占坑

在了解系統(tǒng)的activity,service,broadcastReceiver的啟動(dòng)過(guò)程后,今天將分析下360 DroidPlugin是如何預(yù)注冊(cè)占坑的?本篇文章主要分析Activity預(yù)注冊(cè)占坑,Activity占了坑后又是什么時(shí)候開(kāi)始瞞天過(guò)海欺騙AMS的?先看下Agenda:

  • AndroidMainfest.xml中概覽
  • Activity中關(guān)鍵方法被hook時(shí)機(jī)
  • startActivity被hook
  • handelPerformActivity被hook
  • Activity預(yù)注冊(cè)占坑整體流程圖
  • 瞞天過(guò)海,冒充真實(shí)身份,欺騙AMS

AndroidMainfest.xml中概覽

我們知道所有能用的四大組件都要在Manifest中注冊(cè)聲明,第一步,先看AndroidManifest.xml,雖然在說(shuō)hook機(jī)制時(shí),也有提及過(guò),但是畢竟沒(méi)細(xì)致分析,話不多說(shuō),看代碼上圖:

這里寫(xiě)圖片描述

然后看下各個(gè)屬性的意思

這里寫(xiě)圖片描述

表示一個(gè)activity1原來(lái)屬于task1,但是如果task2啟動(dòng)起來(lái)的話,activity1可能不再屬于task1了,轉(zhuǎn)而投奔task2去了。

這里寫(xiě)圖片描述

功能:?jiǎn)?dòng)硬件加速
缺點(diǎn):占用內(nèi)存
特點(diǎn):可以在Application、Activity、Window、View四個(gè)級(jí)別進(jìn)行硬件加速控制

從Android3.0(API Level 11)開(kāi)始,Android 2D渲染管道能夠更好的支持硬件加速。硬件加速執(zhí)行的所有的繪圖操作都是使用GPU在View對(duì)象的畫(huà)布上來(lái)進(jìn)行的。因?yàn)閱⒂糜布铀贂?huì)增加資源的需求,因此這樣的應(yīng)用會(huì)占用更多的內(nèi)存。

啟用硬件加速的最容易的方法是給整個(gè)應(yīng)用程序都打開(kāi)全局硬件加速功能。如果應(yīng)用程序只使用標(biāo)準(zhǔn)的View和Drawable,那么打開(kāi)全局硬件加速不會(huì)導(dǎo)致任何的不良的繪制效果。但是,因?yàn)橛布铀俨⒉恢С炙械?D圖形繪制操作,所以對(duì)于那些使用定制的View和繪制調(diào)用的應(yīng)用程序來(lái)說(shuō),打開(kāi)全局硬件加速,可以會(huì)影響繪制效果。問(wèn)題通常會(huì)出現(xiàn)在對(duì)那些不可見(jiàn)的元素進(jìn)行了異?;蝈e(cuò)誤的像素渲染。為了避免這種問(wèn)題,Android提供以下級(jí)別,以便可選擇性的啟用或禁止硬件加速:

控制硬件加速,能夠用以下級(jí)別來(lái)控制硬件加速:

1、Application級(jí)別

在應(yīng)用的Android清單文件中,把下列屬性添加到元素中,來(lái)開(kāi)啟整個(gè)應(yīng)用程序的硬件加速。

2、Activity級(jí)別

如果應(yīng)用程序不能夠正確的使用被打開(kāi)的全局硬件加速,那么也可以對(duì)Activity分別進(jìn)行控制。在元素中使用android:hardwareAccelerated屬性,能夠啟用或禁止Activity級(jí)別的硬件加速。以下示例啟用全局的硬件加速,但卻禁止了一個(gè)Activity的硬件加速。

3、Window級(jí)別

如果需要更細(xì)粒度的控制,就可以使用下列代碼來(lái)針對(duì)給定的窗口來(lái)啟用硬件加速:

注意:當(dāng)前不能在Window級(jí)別禁止硬件加速。

這里寫(xiě)圖片描述

4、View級(jí)別

能夠使用下列代碼在運(yùn)行時(shí)針對(duì)一個(gè)獨(dú)立的View對(duì)象來(lái)禁止硬件加速:

這里寫(xiě)圖片描述

注意:當(dāng)前不能在View級(jí)別開(kāi)啟硬件加速。View層除了禁止硬件加速以外,還有其他的功能,更多的相關(guān)信息請(qǐng)看本文的“View層”。

這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

以上就是聲明屬性的含義說(shuō)明,作為背景了解即可。重點(diǎn)看下面的分析

這里寫(xiě)圖片描述

Manifest中注冊(cè)了8個(gè)進(jìn)程,加上主進(jìn)程共9個(gè)
然后第每個(gè)進(jìn)程下面又有26個(gè)Activity注冊(cè),一個(gè)service,一個(gè)contentprovider,那么問(wèn)題來(lái)了,搞這么多注冊(cè)在manifest做什么用?仔細(xì)分類(lèi):就兩類(lèi)一類(lèi)是Activity,一類(lèi)是Dialog,我們知道Dialog是建立在Activity之上的,如果Activity被finish或destory后,就會(huì)報(bào)出異常:android.view.WindowManager$BadTokenException: Unable to add window — token android.os.BinderProxy@438e7108 is not valid; is your activity running?

《插件占坑,四大組件動(dòng)態(tài)注冊(cè)前奏(一) 系統(tǒng)Activity的啟動(dòng)流程》(也可點(diǎn)擊鏈接過(guò)去看詳細(xì)過(guò)程)的activity的啟動(dòng)時(shí)序列圖:

這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

Activity中關(guān)鍵方法被hook時(shí)機(jī)

其中startActivity()和handleLanchActivity()是被DroidPlugin 要欺騙系統(tǒng)的兩個(gè)主要方法:

第一個(gè)方法是最被經(jīng)常使用的startActivity(),hook機(jī)制見(jiàn)《插件開(kāi)發(fā)之360 DroidPlugin源碼分析(二)Hook機(jī)制》中分析,主要是通過(guò)Java的反射機(jī)制替換掉IActivityManager全局對(duì)象,具體IActivityManagerHookHandle的onInstall()方法如下:

這里寫(xiě)圖片描述

這里寫(xiě)圖片描述

第二個(gè)方法是handleLaunchActivity(),這個(gè)方法屬于ActivityThread的一個(gè)叫做H的內(nèi)部類(lèi),前面講Activity啟動(dòng)時(shí),已埋下伏筆,可以參考《插件占坑,四大組件動(dòng)態(tài)注冊(cè)前奏(一) 系統(tǒng)Activity的啟動(dòng)流程》,如果學(xué)過(guò)中間人攻擊協(xié)議的話,我們知道,現(xiàn)個(gè)通信雙方發(fā)出消息后,進(jìn)行消息驗(yàn)證,如果中間人攔截相關(guān)協(xié)議內(nèi)容,通過(guò)一個(gè)代理進(jìn)行轉(zhuǎn)發(fā)出去,從而達(dá)到欺騙的目的,這里暫且理解handleLanchActivity被中間人攻擊了,當(dāng)啟動(dòng)handleLanchActivity時(shí),被DroidPlugin hook后,那多人可能會(huì)想,你怎么hook住hanleLanchActivity呢?別忘了,我們可是在Manifest占了一堆坑的。要是不好理解,可以參看《插件前奏-android黑科技 hook介紹 :http://blog.csdn.net/hejjunlin/article/details/52091833》,可能更直觀些,哪在DroidPlugin中,如何在代碼中瞞天過(guò)海的呢?
我們可以看下:PluginCallbackHook.java,其中有一個(gè)onInstall()方法:

這里寫(xiě)圖片描述

如上代碼也有注釋?zhuān)煽偨Y(jié)為:
1.DroidPlugin不是完全攻擊mH這個(gè)內(nèi)部類(lèi),而是把mH的mCallback成員變量攻擊了,然后替換成了一個(gè)PluginCallback對(duì)象,進(jìn)行消息分發(fā),那么就可以在在PluginCallback的handleMessage()里任意攔截想要分發(fā)的消息,來(lái)欺騙AMS。經(jīng)過(guò)中間人這么一鬧騰,那就能達(dá)到控制這個(gè)區(qū)域的目的了。

最狠的看下面:
上面代碼中,有一個(gè)mH的mCallback,是被攔截攻擊了吧,既然被攔截后又要冒充一個(gè)擔(dān)當(dāng)mH的mCallback職責(zé)相關(guān),(這里暫且夸張的說(shuō))那肯定得扒了它身上的某些特性放到冒充的mCallback吧,如身份驗(yàn)證相關(guān)之類(lèi),所以那原來(lái)的mCallback丟了它的身份相關(guān),不就是廢了,暫且理解為mCallback為null,實(shí)際上有mCallback在未賦值之前,初始化時(shí),本身也是null。然后看下PluginCallback的handleMessage()方法:(ps: PluginCallback簡(jiǎn)直就是仿照ActivityThread中的H內(nèi)部類(lèi)寫(xiě)的,幾乎邏輯一樣,具體可看系統(tǒng)源碼證實(shí))

這里寫(xiě)圖片描述

這里只攔截了一個(gè)消息類(lèi)型為L(zhǎng)AUNCH_ACTIVITY(ActivityThread中的H內(nèi)部類(lèi)中會(huì)有很多消息類(lèi)型,也包含LAUNCH_ACTIVITY)。mCallback不為null,就是發(fā)一些偽裝的消息(因?yàn)槲覀儎倲r截了mCallback),如果為null,返回false,這樣就會(huì)會(huì)再通過(guò)mH調(diào)用回真正ActivityThread的handleLaunchActivity()。(ps:系統(tǒng)發(fā)的消息沒(méi)什么卵用時(shí),我們就不去攔截,暫且理解為這樣)

以上就是兩個(gè)方法怎么被hook相關(guān)分析,也可參考在Hook機(jī)制舉例為IPackageManager的驗(yàn)證簽名被hook的過(guò)程,接下來(lái)就是要看hook中做了什么事?附一張Activity預(yù)注冊(cè)占坑整體流程圖:

這里寫(xiě)圖片描述

前面我們都是在說(shuō)DroidPlugin怎么用中間人攻擊方式,攔截了startActivity()方法和hanleLanchActivity()方法,接下來(lái)要看下攔截了后,怎么把這種身份角色搞變化了(就是一個(gè)怎么扮演冒充的角色過(guò)程):
1.首先得找一個(gè)和真實(shí)的人像的角色,這時(shí)啟用的我們備用人員,也就是事先占的坑stub.ActivityStubxxx。
2.真實(shí)的角色身上有某些特定的特性,如愛(ài)抽煙,頭發(fā)亂糟糟的,像Activity中Intent作為一個(gè)extra傳到另一個(gè)Activity時(shí),還有一些自己的lanchmode(啟動(dòng)方式),theme(主題),這些都是Activity的一些特性,所以stub.ActivityStubxxx也得有這些,否則怎么能達(dá)到冒充呢,這些我們?cè)诖a中早就寫(xiě)好了,所有的那些注冊(cè)的26個(gè)備用人員都是繼承ActivityStub,而ActivityStub是直接繼承Activity,那還說(shuō)啥呢,不就是天然的冒充么?說(shuō)這么多了,直接看代碼IActivityManagerHookHandle$startActvity:
這是一個(gè)靜態(tài)內(nèi)部類(lèi),繼承ReplaceCallingPackageHookedMethodHandler,重寫(xiě)了beforeInvoke方法,暫且理解為在冒充之前的一些準(zhǔn)備工作,如下:

這里寫(xiě)圖片描述

接著再看beforeStartActivity方法:

這里寫(xiě)圖片描述

就是判斷了下Activity的啟動(dòng)模式,接著都調(diào)入doFinshIt(mRunningXXXActivityList),繼續(xù)看此方法:

這里寫(xiě)圖片描述

STUB_NO_ACTIVITY_MAX_NUM為4,上面方法總結(jié)為:runningActivityList(備用activity的list的總數(shù))大于等于3時(shí),就把最早進(jìn)入activityRecord棧中的那個(gè)finish掉,因?yàn)榭泳湍敲炊?,要是都占著不干活,那要它干嘛?/p>

瞞天過(guò)海,冒充真實(shí)身份,欺騙AMS

前面這些,還是小打小鬧,接下來(lái)看一個(gè)核心方法,就是beforeInvoke中的doReplaceIntentForStartActivityAPILow方法:

這里寫(xiě)圖片描述

前面我們說(shuō)了,欺騙了兩個(gè)方法,上面說(shuō)的都是startActivity(),接下來(lái)看另個(gè)一個(gè)方法handleLanchActivity(), 這個(gè)方法在哪呢?我們前面說(shuō)過(guò)有一個(gè)仿照ActivityThread中H內(nèi)部類(lèi)的class叫PluginCallBack,對(duì),handleLaunchActivity就是在接到handleMessage中消息類(lèi)型為L(zhǎng)ANCH_ACTIVITY時(shí)調(diào)用的:

這里寫(xiě)圖片描述
這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

以上就是Activity預(yù)注冊(cè)占坑,并欺騙AMS的過(guò)程,下篇分析Service預(yù)注冊(cè)占坑。

如果你覺(jué)得好,隨手點(diǎn)贊,也是對(duì)筆者的肯定,也可以分享此公眾號(hào)給你更多的人,原創(chuàng)不易

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,208評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,746評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,666評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,477評(píng)論 6 407
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,960評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,200評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,726評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,617評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,807評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,049評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,425評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,674評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,432評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,769評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容