国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

Android APP功能插件化機制的研究與實現(xiàn)

2019-01-11 06:00熊建芳
智能計算機與應用 2019年1期
關鍵詞:插件組件代理

熊建芳

(嶺南師范學院 信息工程學院, 廣東 湛江 524048)

0 引 言

隨著智能手機的大眾化,移動應用層出不窮,目前已經開源的插件化框架有很多,但大多數(shù)針對性比較強,要么針對新功能的增加,要么是bug的修復,并沒有一個框架對二者進行融合;并且這些框架也沒有采取任何安全機制來保障應用的安全。

本文提出了一種Android App插件化機制。這種插件機制按照插件化的粒度分成模塊化更新和熱修復。模塊化更新針對新功能的增加,而熱修復針對類文件中方法級別的修復。在這種機制下用戶無需手動安裝新模塊,APP通過動態(tài)加載的方式就可以進行更新,大大提高了用戶的體驗性,更為開發(fā)者部署應用、更新應用、修復應用的bug提供了很大的方便。

1 總體設計

對于插件化的開發(fā)方式,保證模塊代碼在網(wǎng)絡上的安全性是十分重要的,尤其對于一些敏感性比較高的應用,安全就顯的尤為重要。目前開源的插件化框架對安全性這方面并沒有做相應的保障?;谶@些需求,本文所研究的機制將通過HOOK技術接管系統(tǒng)的部分管理機制,實現(xiàn)動態(tài)加載APK或者是單個dex文件,同時讓這些插件化模塊能夠正常運行。安卓四大組件(Activity、Service、Broadcast Receiver、Content Provider)插件化都會預先注冊代理組件,然后利用這個代理組件向系統(tǒng)發(fā)送數(shù)據(jù)請求,接著利用借尸還魂的方式還原成真正要啟動的組件。在插件化的過程中利用HOOK系統(tǒng)各類關鍵的API和Binder來獲取系統(tǒng)的資源以及管理各插件中組件的生命周期。設計APK的解析模塊,通過這個模塊來解析出APK中的關鍵信息,其中META.INF下的簽名文件對于判斷插件模塊的安全性起到了關鍵性的作用。對于保障應用安全方面,本文采用對比簽名文件信息,驗證簽名是否一致和對dex文件加殼的方式來維護。為實現(xiàn)熱修復,解決mutildex的問題,使用了javassist動態(tài)代碼注入技術。插件化機制的總體框架如圖1所示。

圖1 插件化機制總體框架

利用這個框架可以讓應用在相對安全的情況下實現(xiàn)模塊化更新和熱修復功能,并且也可以讓系統(tǒng)認為插件模塊與宿主應用程序始終為一體。使用該機制開發(fā)的應用,APP在用戶體驗方面將會有質的提升。

2 插件加載模塊

由于在加載插件之前,從網(wǎng)絡上獲取的更新文件下載到本地的固定目錄下。因此在加載插件時可以直接遍歷這個固定目錄,若該目錄下存在符合條件的APK文件或dex文件,系統(tǒng)就會將這些文件加載進入內存。加載插件模塊的流程如圖2所示。

圖2 加載插件模塊流程

3 模塊化更新

3.1 APK解析

普通的應用都是以APK包進行安裝的,APK在正常安裝的過程中,系統(tǒng)會對APK進行自動解析,并且將信息緩存到系統(tǒng)中。在應用請求啟動某個組件時,會自動匹配組件信息并初始化組件、啟動組件。但本文中的APK并不能通過正常方式進行安裝,因此必須對Android系統(tǒng)這一過程進行HOOK,然后執(zhí)行本文的邏輯,完成這一過程。在前面提到需要對dex文件進行保護并且驗證APK簽名,因此可以在該模塊中利用解析APK文件的過程獲取dex文件和簽名文件,并對簽名文件進行驗證和對dex文件進行解密。

通過上面的分析,APK包的解析將是本文研究機制中必須設計的一個模塊。當有新的插件模塊下載到本地固定目錄時,該模塊就會自動解析出對應的信息,并且將其放入系統(tǒng)的緩存目錄下。通過對應用安裝過程源碼的分析,可以得出APK的解析是由PackageParser這個類來負責的,因此本文通過繼承該類,實現(xiàn)自己的邏輯來解析插件的APK包。

3.2 AndroidManifest預注冊

想要啟動插件中的四大組件勢必需要在宿主程序中進行預注冊。對于插件模塊中四大組件的數(shù)量在開發(fā)宿主應用時并不可預測,但是因為系統(tǒng)本身的限制,能同時運行的進程數(shù)量是有限的,同時運行的插件數(shù)量也就有限,因此本文對四大組件中代理組件的注冊數(shù)就可有限化。

為了讓每個插件都能夠獨立的運行在自己的進程中,必須對預注冊組件的process屬性進行賦值,用來區(qū)分不同的進程。因為開發(fā)APP時,在AndroidManifest中注冊的組件可以通過指定process屬性來指定該組件所在的進程。對于Activity而言其啟動模式有4種,除了由于Standard模式每次啟動都是新的Activity,在一個插件中只需為其預先注冊一個Activity,其余模式下啟動的Activity則必須預注冊多個。廣播也具有一定的特殊性,具有2種注冊方式,本文采取的方式是靜態(tài)轉動態(tài)注冊,所以并不需要對其進行預注冊。對于其它的2個組件并不像Activity的生命周期和啟動模式那樣復雜,只需在每個插件中預注冊一個代理組件。

3.3 四大組件的插件化

由于插件模塊中的組件并未在宿主應用的文件中進行注冊,所以必須使用上述預先注冊的四大組件作為代理,利用代理組件向系統(tǒng)發(fā)出相應的請求。在獲得應答后再還原成插件中對應的目標組件,在此過程中本文利用HOOK技術結合動態(tài)代理進行攔截和替換。四大組件攔截替換過程如圖3所示。

圖3 HOOK模塊設計

因為Activity啟動模式復雜,在圖中的攔截替換過程中,本機制會建立一個映射關系,方便系統(tǒng)在做任務棧管理時能夠正確的識別目標組件,從而實現(xiàn)不同的啟動模式。對于Service與ContentProvider的啟動不像Activity那樣復雜,本文只需將目標組件替換為代理組件,最后再進行代理分發(fā)還原。而對于廣播,有動態(tài)和靜態(tài)之分,對于靜態(tài)本文則將其轉動態(tài)進行注冊的。所以本文在APK進行解析時,將獲取的廣播信息通過HOOK的方式加入到動態(tài)廣播的隊列當中,然后當廣播被發(fā)送后,系統(tǒng)會對該隊列中對該廣播感興趣的接收者回調相應的方法。

3.4 緩存機制與插件包管理

Android應用的沙箱機制,是Android系統(tǒng)為了保證應用安全專門設計的[2]。這種安全機制為每個成功安裝的Android應用分配一個以應用包名為路徑的私有空間,程序中很多本地存儲都會選擇該路徑下的私有空間來進行數(shù)據(jù)的存儲。由于插件并沒有進行安裝注冊,所以系統(tǒng)并不會為其分配這樣的空間。而插件本身肯定會遇到需要將數(shù)據(jù)存儲到本地的境況,因此本文通過結合HOOK技術與Java的反射機制來獲取應用程序的IO路徑,在宿主程序私有空間下為插件創(chuàng)建一個空間。然后重定向到這個IO路徑。獲取到IO路徑后,插件就可以進行本地存儲。

插件APK解析完成后,將解析出來的信息緩存到本地目錄,以便應用加載插件,同時也需要將一些關鍵的對象進行緩存,例如加載插件的ClassLoder。在插件進行卸載的同時,需要根據(jù)插件的包名找到對應的本地目錄,將該插件在本地的所有緩存清空。

3.5 HOOK模塊

HOOK模塊主要是為系統(tǒng)在通信過程中插件模塊沒有進行安裝和注冊,導致無法正常訪問系統(tǒng)資源或是加載組件而設計的。本文通過HOOK技術和動態(tài)代理技術來解決這個問題,從而保障插件模塊的正常運行。這項技術主要分為以下2點:一是用于PMS和AMS。應用的啟動和運行都與PMS和AMS相關,尤其是應用與系統(tǒng)進程進行通信,更是與AMS息息相關,因此HOOK PMS和AMS是至關重要的;二是Binder。Android中進程間通信使用最廣泛的方式就是Binder,請求系統(tǒng)服務和獲取系統(tǒng)權限等都需要Binder。因此HOOK Binder對于啟動插件也是不可或缺的。HOOK模塊的設計如圖3所示。

Package Manager Service(下文簡稱PMS)在系統(tǒng)中的作用是完成信息校驗、APK信息獲取和四大組件信息獲取等重要功能。在APK解析、系統(tǒng)啟動組件等過程中系統(tǒng)都會檢查對應包的信息,因為插件并沒有進行安裝注冊,就會拋出異常。因此要正常啟動插件就必須對PMS進行HOOK。從源碼中可以看到真正獲取PMS的方法是應用ContextImpl中的getPackageManager( )。從該方法中可以看到PMS對象是在ActivityThread中并被ApplicationPackageManager包裹了一層。由ActivityThread源碼中可以看出PMS的代理對象是一個靜態(tài)對象,可以對這個對象進行HOOK。因此可以將此作為一個HOOK點。

Ctivity Manager Service(下文簡稱AMS)。AMS對于FrameWork層的作用是非常重要的,四大組件啟動運行都和AMS有著密切的關系。四大組件都是通過調用AMS與系統(tǒng)進程通信的。因此,HOOK AMS顯得尤為關鍵。通過查看startActivity()的源碼,啟動Activity最終都是execStartActivity( )方法。這個方法存在于Instrumentation類中。從該方法中能夠發(fā)現(xiàn)其實ActivityManagerNative是AMS的一個遠程代理對象,這個代理對象是一個單例。因此本文將此作為一個HOOK點,對AMS的這個代理對象進行HOOK。

本框架研究的機制主要是插件請求系統(tǒng)服務或資源,是以Client端的身份進行HOOK Binder的。因此,本文所要HOOK的對象是Binder的代理對象。通過對系統(tǒng)源碼的分析可知獲取系統(tǒng)的服務需要如下2個步驟:

//獲取原始IBinder對象

IBinder b = ServiceManager.getService("service_name");

//轉換為Service接口

IXXInterface in = IXXInterface.Stub.asInterface(b);

//asInterface()方法中返回的對象。

android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

當插件化機制需要訪問對應的系統(tǒng)服務、獲取求權限、訪問系統(tǒng)資源時,都需要用到HOOK模塊,這是插件化的核心。

3.6 熱修復模塊

當應用出現(xiàn)需要修復的bug并需要立即更新時,本文會將需要更新的文件打包成dex文件,而不再是一個APK包。因此熱修復文件不需要經過機制中的APK解析模塊,可以直接進行加載。新類與bug類的包名、類名必須一致,且新類在數(shù)組中的位置又必須優(yōu)先于應用中的bug類。根據(jù)類加載機制的雙親委托模型可知,系統(tǒng)將不再加載bug類。同時為了解決dex文件的引用問題,本文在加載dex文件的過程中需要進行動態(tài)代碼的注入。圖4是熱修復的流程。

圖4 熱修復流程

在Java層面通常用到的動態(tài)特性是反射,但是反射的效率比較低,并且在java層面使用動態(tài)代碼注冊,也不可能實現(xiàn)一個類去引用其它dex文件的類。因此為實現(xiàn)上面的需求,本文使用javassist類庫進行代碼注入。利用Javassist類庫中提供的方法直接在運行時操作Java字節(jié)碼。相比于其它動態(tài)注入代碼的方式,javassist的性能雖然略低,但是提供了一層抽象,相比于直接操作字節(jié)碼的方式javassitst源碼級別的api成本要低,本文選擇使用javassist來進行代碼的注入。在宿主程序開發(fā)完畢后,本文的機制要求去打包第二個dex文件,這個dex文件的目的是讓類去引用不同dex文件中的類,避免被打上特殊的標志。在宿主應用程序中利用javassist類庫編寫相應的代碼對需要代碼注入的類進行動態(tài)注入。

3.7 插件化機制安全模塊

采用驗證APK簽名文件和對dex文件在打包時進行加密、加載前進行解密這兩種方式維護應用的安全。

4 結束語

本文所研究的機制具有以下特點:一是可以在用戶無感知的情況下下載更新模塊、對新功能模塊更新和修復類文件中的bug;二是每個插件模塊都是獨立的,插件之間互不影響,并且可以進行熱插拔;三是熱修復模塊與模塊化更新結合,既實現(xiàn)了大粒度的模塊更新,又實現(xiàn)了小粒度的熱修復功能;四是具有一定的安全機制,可以在一定程度上保障應用的安全。

猜你喜歡
插件組件代理
Kistler全新的Kitimer2.0系統(tǒng)組件:使安全氣囊和安全帶測試更加可靠和高效
創(chuàng)建Vue組件npm包實戰(zhàn)分析
智能機械臂
艦載雷達TR組件沖擊計算方法分析
用好插件瀏覽器標簽頁管理更輕松
《汽車維修技師》誠招代理
1號異星球餐館·不可思議的代理老板
《航空模型》團體代理招募
請個瀏覽器插件全能管家
基于jQUerY的自定義插件開發(fā)