【Android】Xposed 框架解析

前言

Xposed這位老兄大家可能不認(rèn)識织狐,微信自動搶紅包大家聽過吧、微信記錄器作弊大家聽過吧筏勒、地理位置模擬大家聽過吧,我很負(fù)責(zé)任的告訴大家旺嬉,這些都是Xposed干的管行,對的,就是它邪媳,相信大家充著“誰搶我紅包”的憤怒捐顷,也想結(jié)識下這個牛逼的人物吧荡陷,草民在此(淫蕩一笑),我們開始吧迅涮。

Xposed 介紹

大名鼎鼎得Xposed废赞,是Android平臺上最負(fù)盛名的一個框架,百度百科介紹是:“Xposed框架是一款可以在不修改APK的情況下影響程序運(yùn)行(修改系統(tǒng))的框架服務(wù)叮姑,基于它可以制作出許多功能強(qiáng)大的模塊唉地,且在功能不沖突的情況下同時運(yùn)作”,在這個框架下传透,我們可以加載很多插件App耘沼,這些插件App可以直接或間接劫持、篡改朱盐、偽造一些信息群嗤。有了Xposed后,理論上我們的插件APP可以hook到系統(tǒng)任意一個Java進(jìn)程zygote兵琳、systemserver狂秘、systemui。

Xposed 原理

Zygote 進(jìn)程簡析及與Xposed關(guān)系

在Android系統(tǒng)中躯肌,應(yīng)用程序進(jìn)程以及系統(tǒng)服務(wù)進(jìn)程SystemServer都是由Zygote進(jìn)程孵化出來的者春,而Zygote進(jìn)程是由Init進(jìn)程啟動的,Zygote進(jìn)程在啟動時會創(chuàng)建一個Dalvik虛擬機(jī)實(shí)例羡榴,每當(dāng)它孵化一個新的應(yīng)用程序進(jìn)程時碧查,都會將這個Dalvik虛擬機(jī)實(shí)例復(fù)制到新的應(yīng)用程序進(jìn)程里面去,從而使得每一個應(yīng)用程序進(jìn)程都有一個獨(dú)立的Dalvik虛擬機(jī)實(shí)例校仑,這也是Xposed選擇替換app_process的原因忠售。

Zygote進(jìn)程在啟動的過程中,除了會創(chuàng)建一個Dalvik虛擬機(jī)實(shí)例之外迄沫,還會注冊一些Android核心類的JNI方法到Dalvik虛擬機(jī)實(shí)例中去稻扬,以及將Java運(yùn)行時庫加載到進(jìn)程中來。而一個應(yīng)用程序進(jìn)程被Zygote進(jìn)程孵化出來的時候羊瘩,不僅會獲得Zygote進(jìn)程中的Dalvik虛擬機(jī)實(shí)例拷貝泰佳,還會與Zygote一起共享Java運(yùn)行時庫,這也就是可以將XposedBridge這個jar包加載到每一個Android應(yīng)用程序中的原因尘吗,想更多了解Zygote 進(jìn)程可以去看下老羅的文章Android系統(tǒng)進(jìn)程Zygote啟動過程的源代碼分析逝她。

Hook/Replace 簡析

Xposed 框架中真正起作用的是對方法的hook。在Repackage技術(shù)中睬捶,如果要對APK做修改黔宛,則需要修改Smali代碼中的指令,而另一種動態(tài)修改指令的技術(shù)需要在程序運(yùn)行時基于匹配搜索來替換smali代碼擒贸,但因?yàn)榉椒暶鞯亩鄻有耘c復(fù)雜性臀晃,這種方法也比較復(fù)雜觉渴。

在Android系統(tǒng)啟動的時候,zygote進(jìn)程加載XposedBridge將所有需要替換的Method通過JNI方法hookMethodNative指向Native方法
xposedCallHandler徽惋,xposedCallHandler在轉(zhuǎn)入handleHookedMethod這個Java方法執(zhí)行用戶規(guī)定的Hook Func案淋。

Xposed框架的原理是通過替換/system/bin/app_process程序控制zygote進(jìn)程,使得app_process在啟動過程中會加載XposedBridge.jar這個jar包险绘,從而完成對Zygote進(jìn)程及其創(chuàng)建的Dalvik虛擬機(jī)的劫持踢京。
與采取傳統(tǒng)的Inhook方式詳見Dynamic Dalvik Instrumentation這篇文章 相比,Xposed在開機(jī)的時候完成對所有的Hook Function的劫持隆圆,在原Function執(zhí)行的前后加上自定義代碼漱挚,由于是通過安裝基于Xposed框架的App來修改系統(tǒng),所以風(fēng)險會比直接修改系統(tǒng)文件來得少渺氧,有一定風(fēng)險旨涝,如變磚、無限重啟等侣背,需謹(jǐn)慎白华!

工程組成

XposedInstaller

這是Xposed的插件管理和功能控制APP,也就是說Xposed整體管控功能就是由這個APP來完成的贩耐,它包括啟用Xposed插件功能弧腥,下載和啟用指定插件APP,還可以禁用Xposed插件功能等潮太。注意管搪,這個app要正常無誤得運(yùn)行必須能拿到root權(quán)限。

Xposed

這個項(xiàng)目屬于Xposed框架铡买,其實(shí)它就是單獨(dú)搞了一套xposed版的zygote更鲁。這個zygote會替換系統(tǒng)原生的zygote。所以奇钞,它需要由XposedInstaller在root之后放到/system/bin下澡为。

XposedBridge

這個項(xiàng)目也是Xposed框架,它屬于Xposed框架的Java部分景埃,編譯出來是一個XposedBridge.jar包媒至。

XposedTools

Xposed和XposedBridge編譯依賴于Android源碼,而且還有一些定制化的東西谷徙。所以XposedTools就是用來幫助我們編譯XposedXposedBridge的拒啰。

使用示例

環(huán)境搭建

一、下載完慧、安裝XposedInstaller

下載地址

安裝后如圖所示:

XposedInstaller.apk
XposedInstaller.apk

...

二图呢、gradle 配置

dependencies {
    // ** 省略部分代碼
    provided 'de.robv.android.xposed:api:82'
    //如果需要引入文檔,方便查看的話
    provided 'de.robv.android.xposed:api:82:sources'
}

三骗随、AndroidManifest 配置

在application標(biāo)簽下添加配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xxx

    <application xxx>
    
        <!-- 1蛤织、標(biāo)識自己是否為一個Xposed模塊 -->
        <meta-data
            android:name="xposedmodule"
            android:value="true"/>
            
        <!-- 2、Xposed模塊的描述信息 -->
        <meta-data
            android:name="xposeddescription"
            android:value="a sample for xposed"/>
            
        <!-- 3鸿染、支持Xposed框架的最低版本 -->
        <meta-data
            android:name="xposedminversion"
            android:value="53"/>

    </application>

</manifest>

至此指蚜,準(zhǔn)備工作都已完畢,下面可以擴(kuò)展xposed模塊了~

模塊擴(kuò)展

這里我簡單模擬一下獲取imei號的劫持篡改涨椒。

一摊鸡、activity 代碼示例:

        TextView tvImei = (TextView) findViewById(R.id.tv_imei);
        TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        String imei = telephonyManager.getDeviceId();
        tvImei.setText("imei:" + imei);

二、TelephonyHooks

通過源代碼跟蹤蚕冬,我們發(fā)現(xiàn)telephonyManager.getDeviceId()
在android.telephony.TelephonyManager包下免猾,所以我們需要劫持此方法。

public class TelephonyHooks implements IXposedHookLoadPackage {

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        // 可以排除非當(dāng)前包名
        if (!lpparam.packageName.equals("com.walid.xposedlocation")) {
            return;
        }
        XC_MethodHook hook = new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                XposedBridge.log("beforeHookedMethod");
            }

            @Override
            protected void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                methodHookParam.setResult("walid");
                XposedBridge.log("Hook device id is successful!!! ");
            }
        };
        findAndHookMethod("android.telephony.TelephonyManager", lpparam.classLoader, "getDeviceId", hook);
    }

}

三囤热、在assets目錄下創(chuàng)建xposed_init文件并添加TelephonyHooks文件所在完整目錄

例如我的是:

com.walid.xposedlocation.TelephonyHooks

四猎提、運(yùn)行項(xiàng)目

運(yùn)行結(jié)果如下:

劫持篡改前運(yùn)行結(jié)果

此刻有的同學(xué)要吐槽了:

問:說您老忙活半天,這不還是沒篡改成功嗎旁蔼,結(jié)果還是真正的imei號呀锨苏!是在逗我呢嗎?

答: 由于xposed框架從根上Hook了Android Java虛擬機(jī)棺聊,所以它需要root伞租,且每次為它啟用新插件APP都需要重新啟動才能生效,這點(diǎn)草民也有些想吐槽限佩,不過這個權(quán)衡之后草民還是接受了葵诈,畢竟人無完人,何況程序呢祟同。

五作喘、開啟xposed模塊并軟重啟

1、選中模塊

模塊列表

2耐亏、選擇重啟

重新啟動

3徊都、運(yùn)行結(jié)果

運(yùn)行結(jié)果

長嘆一口氣,我們終于看到劫持篡改后的結(jié)果了~

結(jié)語

這篇簡短的教程广辰,草民并沒有像其他人一樣給予大家demo地址之類的暇矫,因?yàn)椴菝癫⒉幌胱尨蠹抑苯酉螺ddemo,run一下就可以了择吊,還是希望大家多動手李根,同時如果有不清楚的同學(xué),隨時聯(lián)系草民几睛,同時這樣的hook技術(shù)可以應(yīng)用到任何場合房轿,包括反編譯、分析競品、植入廣告囱持、搶紅包等等夯接,還是希望將技術(shù)應(yīng)用到該用的地方,而不是應(yīng)用在非法或者違法常規(guī)的事情上面纷妆,忘謹(jǐn)記?浮!掩幢!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逊拍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子际邻,更是在濱河造成了極大的恐慌芯丧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件世曾,死亡現(xiàn)場離奇詭異缨恒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)度硝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門肿轨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蕊程,你說我怎么就攤上這事椒袍。” “怎么了藻茂?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵驹暑,是天一觀的道長。 經(jīng)常有香客問我辨赐,道長优俘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任掀序,我火速辦了婚禮帆焕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘不恭。我一直安慰自己叶雹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布换吧。 她就那樣靜靜地躺著折晦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沾瓦。 梳的紋絲不亂的頭發(fā)上满着,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天谦炒,我揣著相機(jī)與錄音,去河邊找鬼风喇。 笑死宁改,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的响驴。 我是一名探鬼主播透且,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼豁鲤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鲸沮,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤琳骡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后讼溺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體楣号,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年怒坯,在試婚紗的時候發(fā)現(xiàn)自己被綠了炫狱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡剔猿,死狀恐怖视译,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情归敬,我是刑警寧澤酷含,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站汪茧,受9級特大地震影響椅亚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舱污,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一呀舔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扩灯,春花似錦媚赖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至丧失,卻和暖如春豺妓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工琳拭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留训堆,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓白嘁,卻偏偏與公主長得像坑鱼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子絮缅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,749評論 25 707
  • 安全博客 > 技術(shù)研究 > 淺談android hook技術(shù) 淺談android hook技術(shù) 您當(dāng)前的位置:...
    光劍書架上的書閱讀 6,150評論 0 8
  • afinalAfinal是一個android的ioc鲁沥,orm框架 https://github.com/yangf...
    passiontim閱讀 15,408評論 2 45
  • 人生如跑步,或領(lǐng)跑耕魄,或逃跑画恰,僅在你的一念之間。 人生就像一場跑步吸奴,少年時候允扇,是這場跑步的初始,每個人都充滿了生機(jī)與...
    鳳涼閱讀 287評論 3 12
  • 不斷創(chuàng)新则奥,不斷進(jìn)步考润,是中科貼針灸從不改變的使命! 銘記歷史读处,創(chuàng)造歷史糊治,是中科貼針灸從不遺忘的初衷! 中科貼針灸档泽,創(chuàng)...
    das0609閱讀 2,117評論 0 0