Xposed技術(shù)和熱修復(fù)

熱修復(fù)技術(shù)


APP提早發(fā)出去的包队他,如果出現(xiàn)客戶端的問(wèn)題徒役,實(shí)在是干著急,覆水難收于游。因此線上修復(fù)方案迫在眉睫毁葱。

概述

基于Xposed中的思想,通過(guò)修改c層的Method實(shí)例描述贰剥,來(lái)實(shí)現(xiàn)更改與之對(duì)應(yīng)的java方法的行為倾剿,從而達(dá)到修復(fù)的目的。

Xposed

誕生于XDA論壇蚌成,類似一個(gè)應(yīng)用平臺(tái)前痘,不同的是其提供諸多系統(tǒng)級(jí)的應(yīng)用〉S牵可實(shí)現(xiàn)許多神奇的功能芹缔。Xposed需要以越獄為前提,像是iOS中的cydia瓶盛。

Xposed可以修改任何程序的任何java方法(需root)最欠,github上提供了XposedInstaller,是一個(gè)android app惩猫。提供很多framework層芝硬,應(yīng)用層級(jí)的程序。開(kāi)發(fā)者可以為其開(kāi)發(fā)一些系統(tǒng)或應(yīng)用方面的插件轧房,自定義android系統(tǒng)拌阴,它甚至可以做動(dòng)態(tài)權(quán)限管理(XposedMods)。

Android系統(tǒng)啟動(dòng)與應(yīng)用啟動(dòng)

Zygote進(jìn)程是Android手機(jī)系統(tǒng)啟動(dòng)后锯厢,常駐的一個(gè)名為‘受精卵’的進(jìn)程皮官。

  • zygote的啟動(dòng)實(shí)現(xiàn)腳本在/init.rc文件中
  • 啟動(dòng)過(guò)程中執(zhí)行的二進(jìn)制文件在/system/bin/app_process

任何應(yīng)用程序啟動(dòng)時(shí),會(huì)從zygote進(jìn)程fork出一個(gè)新的進(jìn)程实辑。并裝載一些必要的class捺氢,invoke一些初始化方法。這其中包括像:

  • ActivityThread
  • ServiceThread
  • ApplicationPackageManager

等應(yīng)用啟動(dòng)中必要的類剪撬,觸發(fā)必要的方法摄乒,比如:handleBindApplication,將此進(jìn)程與對(duì)應(yīng)的應(yīng)用綁定的初始化方法残黑;同時(shí)馍佑,會(huì)將zygote進(jìn)程中的dalvik虛擬機(jī)實(shí)例復(fù)制一份,因此每個(gè)應(yīng)用程序進(jìn)程都有自己的dalvik虛擬機(jī)實(shí)例梨水;會(huì)將已有Java運(yùn)行時(shí)加載到進(jìn)程中拭荤;會(huì)注冊(cè)一些android核心類的jni方法到虛擬機(jī)中,支撐從c到j(luò)ava的啟動(dòng)過(guò)程疫诽。

Xposed做了手腳

Xposed在這個(gè)過(guò)程改寫(xiě)了app_process(源碼在Xposed : a modified app_process binary)舅世,替換/system/bin/app_process這個(gè)二進(jìn)制文件旦委。然后做了兩個(gè)事:

  1. 通過(guò)Xposed的hook技術(shù),在上述過(guò)程中雏亚,對(duì)上面提到的那些加載的類的方法hook缨硝。
  2. 加載XposedBridge.jar

這時(shí)hook必要的方法是為了方便開(kāi)發(fā)者為它開(kāi)發(fā)插件,加載XposedBridge.jar是為動(dòng)態(tài)hook提供了基礎(chǔ)罢低。在這個(gè)時(shí)候加載它意味著查辩,所有的程序在啟動(dòng)時(shí),都可以加載這個(gè)jar(因?yàn)樯厦嫣岬降膄ork過(guò)程)网持。結(jié)合hook技術(shù)宜岛,從而達(dá)到了控制所有程序的所有方法。

為獲得/system/bin/目錄的讀寫(xiě)權(quán)限翎碑,因而需要以root為前提谬返。

Xposed的hook思想

那么Xposed是怎么hook java方法的呢?要從XposedBridge看起日杈,重點(diǎn)在
XposedBridge.hookmethod(原方法的Member對(duì)象遣铝,含有新方法的XC_MethodHook對(duì)象);莉擒,這里會(huì)調(diào)到

private native synchronized static void hookMethodNative(Member method, Class<?> declaringClass, int slot, Object additionalInfo);

這個(gè)native的方法酿炸,通過(guò)這個(gè)方法,可以讓所hook的方法涨冀,轉(zhuǎn)向native層的一個(gè)c方法填硕。如何做到?

When a transmit from java to native occurs, dvm sets up a native stack.
In dvmCallJNIMethod(), dvmPlatformInvoke is used to call the native method(signature in Method.insns).

在jni這個(gè)中間世界里鹿鳖,類型數(shù)據(jù)由jni表來(lái)溝通java和c的世界扁眯;方法由c++指針結(jié)合DVM*系(如dvmSlotToMethod,dvmDecodeIndirectRef等方法)的api方法,操作虛擬機(jī)翅帜,從而實(shí)現(xiàn)java方法與c方法的世界姻檀。

那么hook的過(guò)程是這樣:首先通過(guò)dexclassload來(lái)load所要hook的方法,分析類后涝滴,進(jìn)c層绣版,見(jiàn)代碼XposedBridge_hookMethodNative方法,拿到要hook的Method類歼疮,然后通過(guò)dvmslotTomethod方法獲取Method*指針杂抽,

Method* method = dvmSlotToMethod(declaredClass, slot);

declaredClass就是所hook方法所在的類,對(duì)應(yīng)的jobject韩脏。slot是Method類中缩麸,描述此java對(duì)象在vm中的索引;那么通過(guò)這個(gè)方法赡矢,我們就獲取了c層的Method指針,通過(guò)

SET_METHOD_FLAG(method, ACC_NATIVE);

將該方法標(biāo)記為一個(gè)native方法匙睹,然后通過(guò)

method->nativeFunc = &hookedMethodCallback;

定向c層方法到hookedMethodCallback愚屁,這樣當(dāng)被hook的java方法執(zhí)行時(shí)济竹,就會(huì)調(diào)到c層的hookedMethodCallback方法痕檬。

通過(guò)meth->nativeFunc重定向MethodCallBridge到hookedMethodCallback這個(gè)方法上,控制這個(gè)c++指針是無(wú)視java的private的送浊。

另外梦谜,在method結(jié)構(gòu)體中有

method->insns = (const u2*) hookInfo;

用insns指向替換成為的方法,以便hookedMethodCallback可以獲取真正期望執(zhí)行的java方法袭景。

現(xiàn)在所有被hook的方法唁桩,都指向了hookedMethodCallbackc方法中,然后在此方法中實(shí)現(xiàn)調(diào)用替換成為的java方法耸棒。

從Xposed提煉精髓

回顧Xposed荒澡,以root為必要條件,在app_process加載XposedBidge.jar与殃,從而實(shí)現(xiàn)有hook所有應(yīng)用的所有方法的能力单山;而后續(xù)動(dòng)態(tài)hook應(yīng)用內(nèi)的方法,其實(shí)只是load了從zypote進(jìn)程復(fù)制出來(lái)的運(yùn)行時(shí)的這個(gè)XposedBidge.jar幅疼,然后hook而已米奸。因此,若在一個(gè)應(yīng)用范圍內(nèi)的hook爽篷,root不是必須的悴晰,只是單純的加載hook的實(shí)現(xiàn)方法,即可修改本應(yīng)用的方法逐工。

業(yè)界內(nèi)也不乏通過(guò)「修改BaseDexClassLoader中的pathList铡溪,來(lái)動(dòng)態(tài)加載dex」方式實(shí)現(xiàn)熱修復(fù)。后者純java實(shí)現(xiàn)泪喊,但需要hack類的優(yōu)化流程棕硫,將打CLASS_ISPREVERIFIED標(biāo)簽的類,去除此標(biāo)簽窘俺,以解決類與類引用不在一個(gè)dex中的異常問(wèn)題饲帅。這會(huì)放棄dex optimize對(duì)啟動(dòng)運(yùn)行速度的優(yōu)化。原則上瘤泪,這對(duì)于方法數(shù)沒(méi)有大到需要multidex的應(yīng)用灶泵,損失更明顯。而前者不觸犯原有的優(yōu)化流程对途,只點(diǎn)殺需要hook的方法赦邻,更為純粹、有效实檀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惶洲,一起剝皮案震驚了整個(gè)濱河市按声,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恬吕,老刑警劉巖签则,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異铐料,居然都是意外死亡渐裂,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門钠惩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)柒凉,“玉大人,你說(shuō)我怎么就攤上這事篓跛∠ダ蹋” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵愧沟,是天一觀的道長(zhǎng)蔬咬。 經(jīng)常有香客問(wèn)我,道長(zhǎng)央渣,這世上最難降的妖魔是什么计盒? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮芽丹,結(jié)果婚禮上北启,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布速那。 她就那樣靜靜地躺著,像睡著了一般懈涛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泳猬,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天批钠,我揣著相機(jī)與錄音,去河邊找鬼得封。 笑死埋心,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的忙上。 我是一名探鬼主播拷呆,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了茬斧?” 一聲冷哼從身側(cè)響起腰懂,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎项秉,沒(méi)想到半個(gè)月后绣溜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伙狐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年涮毫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贷屎。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖艘虎,靈堂內(nèi)的尸體忽然破棺而出唉侄,到底是詐尸還是另有隱情,我是刑警寧澤野建,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布属划,位于F島的核電站,受9級(jí)特大地震影響候生,放射性物質(zhì)發(fā)生泄漏同眯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一唯鸭、第九天 我趴在偏房一處隱蔽的房頂上張望须蜗。 院中可真熱鬧,春花似錦目溉、人聲如沸明肮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柿估。三九已至,卻和暖如春陷猫,著一層夾襖步出監(jiān)牢的瞬間秫舌,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工绣檬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留足陨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓河咽,卻偏偏與公主長(zhǎng)得像钠右,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子忘蟹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,114評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理飒房,服務(wù)發(fā)現(xiàn)搁凸,斷路器,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 年前在年底的時(shí)候,瘋狂的想跳槽嚼松,為什么嫡良?因?yàn)椴凰?..... 最后面試頁(yè)面了,還是留在了公司沒(méi)選擇走献酗,當(dāng)然對(duì)方of...
    箱貓日和閱讀 567評(píng)論 0 0
  • 春秋富寝受,莫使流光消度。 萬(wàn)象大千不盡數(shù)罕偎,光陰難永駐很澄。 瑯瑯書(shū)聲漸入,褪去浮華庸碌颜及。 莫待朽年回首顧甩苛,空留斜日暮。
    yu_hin_閱讀 148評(píng)論 0 0
  • 假期第一天俏站,約了熟識(shí)的中國(guó)學(xué)生到家里吃火鍋讯蒲。身在國(guó)外的中國(guó)學(xué)生聚會(huì),最普遍的兩種吃法肄扎,一是火鍋墨林,二是包餃子。不過(guò)相...
    四月晴天的日志閱讀 170評(píng)論 0 0