萬(wàn)物皆可Hook!重新?lián)炱?a target="_blank" href="http://m.bai1xia.com/news/tags-1077.html"style="font-weight:bold;">Hook神器-Xposed框架

      網(wǎng)友投稿 2190 2025-04-02

      引言


      這個(gè)Hook不是鄧紫棋要給你唱的Hook哦!而是在程序界流傳的強(qiáng)大秘技-Hook函數(shù),Hook原意是指鉤子,它表示的就是在某個(gè)函數(shù)的上下文做自定義的處理來(lái)實(shí)現(xiàn)我們想要的黑科技。

      在很多技術(shù)領(lǐng)域都存在的這種Hook技術(shù),比如下面這些:

      在Python的Web框架中,如Django,F(xiàn)lask都存在這種Hook技術(shù),可以在請(qǐng)求的上下文,應(yīng)用的上下文做自定義操作。

      在Scrapy框架中,可以自定義MiddlerWare,在請(qǐng)求,解析的時(shí)候做自定操作。

      在K8S編排框架中,我們也可以在執(zhí)行某些函數(shù)的上下文中插入Hook函數(shù),這也是和Web框架同理

      而今天我們講解的是關(guān)于Android的Hook技術(shù),而有一款神器能夠幫助我們快速地開(kāi)發(fā)Hook模塊,也就是Xposed框架。其實(shí)網(wǎng)上的關(guān)于Xposed模塊編寫(xiě)的教程可謂是一抓一大把。但由于時(shí)間的推移,很多工具和方法都發(fā)生了變化(如Eclipse退出安卓編程舞臺(tái),AndroidStudio?不斷升級(jí)導(dǎo)致其一些設(shè)置也隨之變化等)也正因此,網(wǎng)上的教程往往有一些時(shí)限性,比如現(xiàn)如今?provide?這個(gè)關(guān)鍵字已經(jīng)被舍棄了卻仍有人在用,還有些說(shuō)要把jar包放到lib文件夾而非libs文件夾……種種錯(cuò)誤或者落伍的教程對(duì)新手產(chǎn)生了很大的誤導(dǎo)。之前也搞過(guò)一陣子X(jué)posed框架,而今天在重新部署環(huán)境的時(shí)候參考某些教程的時(shí)候也遇到了很多的坑,所以想重新結(jié)合最新的配套工具寫(xiě)個(gè)小教程,主要講解的以下兩個(gè)方面:

      Xposed框架介紹以及原理

      Xposed框架實(shí)戰(zhàn)

      Xposed框架介紹以及原理

      Xposed是Github上rovo89大佬設(shè)計(jì)的一個(gè)針對(duì)Android平臺(tái)的動(dòng)態(tài)劫持項(xiàng)目,通過(guò)替換/system/bin/app_process程序控制Zygote進(jìn)程,使得app_process在啟動(dòng)過(guò)程中會(huì)加載XposedBridge.jar這個(gè)jar包,從而完成對(duì)Zygote進(jìn)程及其創(chuàng)建的Dalvik虛擬機(jī)的劫持。

      因?yàn)閄posed工作原理是在/system/bin目錄下替換文件,在install的時(shí)候需要root權(quán)限,但是運(yùn)行時(shí)不需要root權(quán)限。

      看到這里很多人會(huì)很懵,什么是Zygote?簡(jiǎn)單來(lái)說(shuō)在Android系統(tǒng)中,應(yīng)用程序進(jìn)程都是由Zygote進(jìn)程孵化出來(lái)的,而Zygote進(jìn)程是由Init進(jìn)程啟動(dòng)的。Zygote進(jìn)程在啟動(dòng)時(shí)會(huì)創(chuàng)建一個(gè)Dalvik虛擬機(jī)實(shí)例,每當(dāng)它孵化一個(gè)新的應(yīng)用程序進(jìn)程時(shí),都會(huì)將這個(gè)Dalvik虛擬機(jī)實(shí)例復(fù)制到新的應(yīng)用程序進(jìn)程里面去,而一個(gè)應(yīng)用程序進(jìn)程被Zygote進(jìn)程孵化出來(lái)的時(shí)候,不僅會(huì)獲得Zygote進(jìn)程中的Dalvik虛擬機(jī)實(shí)例拷貝,還會(huì)與Zygote一起共享Java運(yùn)行時(shí)庫(kù)。這也就是可以將XposedBridge這個(gè)jar包加載到每一個(gè)Android應(yīng)用程序中的原因。XposedBridge有一個(gè)私有的Native(JNI)方法hookMethodNative,這個(gè)方法也在app_process中使用。這個(gè)函數(shù)提供一個(gè)方法對(duì)象利用Java的Reflection機(jī)制來(lái)對(duì)內(nèi)置方法覆寫(xiě)。。。。等等這些都會(huì)借鑒各路大神的思路和分析,總而言之,就是從底層替換方法,可以讓我們?cè)诓恍薷腁PK源碼的情況下,通過(guò)自己編寫(xiě)的模塊來(lái)影響程序運(yùn)行的框架服務(wù),實(shí)現(xiàn)類似于自動(dòng)搶紅包、微信消息自動(dòng)回復(fù)等功能。

      其實(shí),從本質(zhì)上來(lái)講,Xposed模塊也是一個(gè)Android程序。但與普通程序不同的是,想要讓寫(xiě)出的Android程序成為一個(gè)``Xposed 模塊,要額外多完成以下四個(gè)硬性任務(wù):

      1、讓手機(jī)上的xposed框架知道我們安裝的這個(gè)程序是個(gè)xposed模塊。 2、模塊里要包含有xposed的API的jar包,以實(shí)現(xiàn)下一步的hook操作。 3、這個(gè)模塊里面要有對(duì)目標(biāo)程序進(jìn)行hook操作的方法。 4、要讓手機(jī)上的xposed框架知道,我們編寫(xiě)的xposed模塊中,哪一個(gè)方法是實(shí)現(xiàn)hook操作的。

      這就引出我即將要介紹的四大件(與前四步一一對(duì)照):

      萬(wàn)物皆可Hook!重新?lián)炱餒ook神器-Xposed框架

      1、AndroidManifest.xml2、XposedBridgeApi-xx.jar?與?build.gradle3、實(shí)現(xiàn)hook操作的具體代碼 4、xposed_Init

      牢記以上四大件,按照順序一個(gè)一個(gè)實(shí)現(xiàn),就能完成我們的第一個(gè)Xposed模塊編寫(xiě)。以上的原理我們大致就介紹這么多,下面我們實(shí)戰(zhàn)開(kāi)始吧!

      Xposed框架實(shí)戰(zhàn)

      我們使用的IDE是Android Studio,首先打開(kāi)AndroidStudio(以版本3.4.2為例,還在用老版本的請(qǐng)升級(jí)),建立一個(gè)工程,提示我們選擇“Activity”,那就選一個(gè)Empty Activity吧。(這個(gè)是模塊的界面,隨意選擇即可)。

      我們可以把項(xiàng)目查看方式設(shè)置為Project模式,以方便查看。然后在 “項(xiàng)目名稱/app/src/main/”目錄下找到AndroidManifest.xml,打開(kāi)這個(gè)文件,并在指定位置插入以下三段代碼:

      ???????? ????????

      效果如圖:

      插入代碼之后,我們可以點(diǎn)擊Run運(yùn)行App。

      不過(guò),此時(shí)會(huì)出現(xiàn)如圖提示,也就是缺少Device設(shè)備來(lái)運(yùn)行這個(gè)App

      下一步我們要把手機(jī)連接Android Studio,連接的辦法很多,包括通過(guò)USB連接(物理連接)和Wifi連接(也就是網(wǎng)絡(luò)連接),我們?yōu)榱斯?jié)省方法,就采用物理連接,Ps: 有關(guān)于遠(yuǎn)程連接可以參考這篇文章,連接好我們的實(shí)體機(jī)之后我們點(diǎn)擊這里

      我們等待Android Studio連接手機(jī),連接好我們就可以看到在Logcat選項(xiàng)里面看到我們的手機(jī)運(yùn)行的日志報(bào)告。

      有如圖所示的日志打印之后我們就會(huì)發(fā)現(xiàn)我們就可以運(yùn)行了,點(diǎn)擊Run之后會(huì)提示我們的手機(jī)安裝我們剛才剛寫(xiě)的Apk,不過(guò)我的手機(jī)提示安裝時(shí)驗(yàn)證超時(shí),不能直接安裝,苦惱,以后選手機(jī)也要選個(gè)正常的。關(guān)于Android Studio安裝Apk失敗的原因可以參考這篇文章,既然我們不能直接安裝Apk,我們就使用adb直接來(lái)安裝

      安裝好應(yīng)用之后我們?cè)赬posed框架中勾選我們剛才的模塊,然后我們重啟一下Xposed框架,就可以啦

      這一步只是說(shuō)明Xposed框架已經(jīng)認(rèn)出了我們寫(xiě)的程序。但先別高興太早——雖然框架已經(jīng)覺(jué)得他是一個(gè)Xposed模塊了,但我們自己心里清楚,這個(gè)模塊還啥都不會(huì)干呢。下一步,我們讓這個(gè)模塊長(zhǎng)點(diǎn)本事。

      我們知道,Xposed模塊主要功能是用來(lái)Hook其他程序的各種函數(shù)。但是,如何讓前一步中的那個(gè)“一窮二白”的模塊長(zhǎng)本事呢?那就要引入?XposedBridgeApi.jar?這個(gè)包,你可以理解為一把***,模塊有了這把寶刀才能施展出Hook本領(lǐng)。很多以前的老教程都需要手動(dòng)下載諸如XposedBridgeApi-54.jar、?XposedBridgeApi-82.jar等jar包,然后手工導(dǎo)入到libs目錄里,才能走下一步道路,而這些jar沒(méi)有官方的渠道來(lái)安裝,通常只是一個(gè)傳一個(gè)的,都不知道變成了什么版本。其實(shí)在最新的AndroidStudio 3.1以后,我們完全不用這么麻煩,只需要多寫(xiě)一行代碼,就讓AndroidStuido自動(dòng)給我們配置XposedBridgeApi.jar!下面操作開(kāi)始:

      在?“項(xiàng)目名稱/app/src/main/”目錄下找到build.gradle,在圖示位置加上:

      repositories?{ ????jcenter() } compileOnly?'de.robv.android.xposed:api:82'compileOnly?'de.robv.android.xposed:api:82:sources'

      這句代碼是告訴AndroidStuido使用jcenter作為代碼倉(cāng)庫(kù),從這個(gè)倉(cāng)庫(kù)里遠(yuǎn)程尋找?de.robv.android.xposed:api:82這個(gè)API。這個(gè)網(wǎng)上很少有Xposed教程介紹它的!(我們不用自己找XposedBridgeApi.jar了。注意!此處要用compileOnly這個(gè)修飾符!網(wǎng)上有些寫(xiě)的是provide,但是現(xiàn)在已經(jīng)停用了!坑人啊!)

      寫(xiě)完之后,?build.gradle會(huì)提示文件已經(jīng)修改,是否同步。點(diǎn)擊?“sync now”,同步即可:

      等待依賴構(gòu)建完成

      【Ps:如果網(wǎng)絡(luò)不通,或者同步不暢,就不要進(jìn)行第三步的repositories { jcenter()}這個(gè)步驟了,改做這個(gè)步驟:手動(dòng)下載XposedBridgeApi-82.jar,拖放到“項(xiàng)目名稱/app/libs/”里面(不是網(wǎng)上說(shuō)的單獨(dú)建立lib文件夾,那是很久以前的故事了!),然后右鍵“Add As Library”自行添加這個(gè)jar包。而compileOnly ‘de.robv.android.xposed:api:82′和?compileOnly ‘de.robv.android.xposed:api:82:sources’這兩句仍然照常添加。】

      好了,我們現(xiàn)在已經(jīng)搞好了所有的準(zhǔn)備工作。下一步,就要開(kāi)始“施展刀法”(編寫(xiě)hook代碼)了。

      在“施展刀法”(編寫(xiě)hook代碼)之前,我們先要立一個(gè)靶子。在界面上畫(huà)一個(gè)按鈕,并在MainAcitiviy里寫(xiě)代碼如下:

      package?com.example.wx;import?android.support.v7.app.AppCompatActivity;import?android.os.Bundle;import?android.view.View;import?android.widget.Button;import?android.widget.Toast;public?class?MainActivity?extends?AppCompatActivity?{????private?Button?button;????@Override ????protected?void?onCreate(Bundle?savedInstanceState)?{????????super.onCreate(savedInstanceState); ????????setContentView(R.layout.activity_main); ????????button?=?(Button)?findViewById(R.id.button); ????????button.setOnClickListener(new?View.OnClickListener()?{????????????public?void?onClick(View?v)?{ ????????????????Toast.makeText(MainActivity.this,?toastMessage(),?Toast.LENGTH_SHORT).show(); ????????????} ????????}); ????}????public?String?toastMessage()?{????????return?"我未被劫持"; ????} }

      而在頁(yè)面布置的文件中,也就是activity_main.xml中增加如下紅框的代碼

      這個(gè)靶子很簡(jiǎn)單:MainActivity界面有個(gè)按鈕,點(diǎn)擊按鈕后會(huì)彈出一個(gè)toast提示,該提示的內(nèi)容由toastMessage()方法提供,而toastMessage()的返回值為“我未被劫持”。

      現(xiàn)在,我們已經(jīng)做好了我們的App了,下面我們正式開(kāi)始“施展刀法”(編寫(xiě)hook代碼) 來(lái)hook我們的MainActivity并修改這個(gè)類的toastMessage()方法,讓它的返回值為“你已被劫持”:

      package?com.example.wx;import?de.robv.android.xposed.IXposedHookLoadPackage;import?de.robv.android.xposed.XC_MethodHook;import?de.robv.android.xposed.XposedBridge;import?de.robv.android.xposed.XposedHelpers;import?de.robv.android.xposed.callbacks.XC_LoadPackage;public?class?HookTest?implements?IXposedHookLoadPackage?{????public?void?handleLoadPackage(XC_LoadPackage.LoadPackageParam?loadPackageParam)?throws?Throwable?{????????if?(loadPackageParam.packageName.equals("com.example.root.xposd_hook_new"))?{ ????????????XposedBridge.log("?has?Hooked!"); ????????????Class?clazz?=?loadPackageParam.classLoader.loadClass(????????????????????"com.example.root.xposd_hook_new.MainActivity"); ????????????XposedHelpers.findAndHookMethod(clazz,?"toastMessage",?new?XC_MethodHook()?{????????????????protected?void?beforeHookedMethod(MethodHookParam?param)?throws?Throwable?{????????????????????super.beforeHookedMethod(param);????????????????????//XposedBridge.log("?has?Hooked!"); ????????????????}????????????????protected?void?afterHookedMethod(MethodHookParam?param)?throws?Throwable?{ ????????????????????param.setResult("你已被劫持"); ????????????????} ????????????}); ????????} ????} }

      由代碼可知,我們是通過(guò)IXposedHookLoadPackage接口中的handleLoadPackage方法來(lái)實(shí)現(xiàn)Hook并篡改程序的輸出結(jié)果的。代碼中“com.example.wx”是目標(biāo)程序的包名,”com.example.wx.MainActivity”是想要Hook的類,“toastMessage”是想要Hook的方法。我們?cè)赼fterHookedMethod方法(用來(lái)定義Hook了目標(biāo)方法之后的操作)中,修改了toastMessage()方法的返回值為“你已被劫持”。在完成代碼編寫(xiě)之前,說(shuō)一下為什么要Hook toastMessage這個(gè)方法,我們先用Jadx查看一下我們Apk的源代碼

      這個(gè)源碼是沒(méi)有經(jīng)過(guò)混淆的,所以我們可以看到這個(gè)源碼和我們之前寫(xiě)的一樣,我們根據(jù)項(xiàng)目結(jié)構(gòu)可以判斷出我們需要Hook的函數(shù)。

      OK,以上用來(lái)hook的代碼編寫(xiě)完畢,讓我們進(jìn)行下一步操作。

      右鍵點(diǎn)擊?“main ”文件夾 , 選擇new –> Folder –>Assets Folder,新建assets文件夾:

      然后右鍵點(diǎn)擊?assets文件夾,?new–> file,文件名為xposed_init(文件類型選text),并在其中寫(xiě)上入口類的完整路徑(就是自己編寫(xiě)的那一個(gè)Hook類),這樣,Xposed框架就能夠從這個(gè)xposed_init讀取信息來(lái)找到模塊的入口,然后進(jìn)行Hook操作了:

      好了,曙光就在前面!最后選擇禁用Instant Run: 單擊?File -> Settings -> Build, Execution, Deployment -> Instant Run,把勾全部去掉。

      我們重新之前的安裝Xposed模塊的方法,運(yùn)行模塊,點(diǎn)擊,奇跡出現(xiàn)~

      大功告成!!!

      結(jié)語(yǔ)

      從上面的實(shí)戰(zhàn)中我們可以發(fā)現(xiàn)Hook的基本原理以及步驟,重新看看我們之前說(shuō)的四大步,Hook的關(guān)鍵其實(shí)我們需要知道針對(duì)哪個(gè)模塊的哪個(gè)方法進(jìn)行Hook

      1、讓手機(jī)上的xposed框架知道我們安裝的這個(gè)程序是個(gè)xposed模塊。 2、模塊里要包含有xposed的API的jar包,以實(shí)現(xiàn)下一步的hook操作。 3、這個(gè)模塊里面要有對(duì)目標(biāo)程序進(jìn)行hook操作的方法。 4、要讓手機(jī)上的xposed框架知道,我們編寫(xiě)的xposed模塊中,哪一個(gè)方法是實(shí)現(xiàn)hook操作的。

      像我們這個(gè)例子很簡(jiǎn)單,沒(méi)有特意的進(jìn)行代碼混淆以及程序入口改寫(xiě)等等,我們尋找還是很簡(jiǎn)單的,一般市面上的App都是有很多反Xposed的行為,我們其實(shí)要學(xué)習(xí)的還有很多,這個(gè)小教程就當(dāng)做個(gè)小入門(mén)吧。

      下一篇文章和最近工作上的需求有關(guān)系,針對(duì)的是2019.10.28之后搜狗微信關(guān)閉了在某些公眾號(hào)內(nèi)搜索的功能,所以我們想要獲取最新的公眾號(hào)文章就不能采取搜狗微信這個(gè)渠道了,網(wǎng)上有很多教程都在談?wù)撈渌姆椒ǎ啾容^來(lái)說(shuō),還是Hook這個(gè)渠道是最實(shí)際的,我們將會(huì)在之后的文章里詳細(xì)談?wù)摚蠹铱梢云诖幌聗

      注意:??項(xiàng)目已經(jīng)完成,想要獲得源碼可以關(guān)注下面的微信號(hào),回復(fù)“hook入門(mén)”即可獲得項(xiàng)目地址以及現(xiàn)成的Apk

      號(hào)主介紹

      前兩年在二線大廠工作,目前在創(chuàng)業(yè)公司搬磚

      接觸方向是爬蟲(chóng)和云原生架構(gòu)方面

      有豐富的反爬攻克經(jīng)驗(yàn)以及云原生二次開(kāi)發(fā)經(jīng)驗(yàn)

      其他諸如數(shù)據(jù)分析、黑客增長(zhǎng)也有所涉獵

      做過(guò)百余人的商業(yè)分享以及多次開(kāi)辦培訓(xùn)課程

      目前也是CSDN博客專家和華為云享專家

      震驚 | 只需3分鐘!極速部署個(gè)人Docker云平臺(tái)

      深入理解Python的TLS機(jī)制和Threading.local()

      我為什么不建議你使用Python3.7.3?

      下一代容器架構(gòu)已出,Docker何去何處?看看這里的6問(wèn)6答!!

      公眾號(hào)內(nèi)回復(fù)“私藏資料”即可領(lǐng)取爬蟲(chóng)高級(jí)逆向教學(xué)視頻以及多平臺(tái)的中文數(shù)據(jù)集

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:EXCEL2013表格中旋轉(zhuǎn)表格的效果怎么制作(excel如何旋轉(zhuǎn)表格)
      下一篇:怎么用WPS表格實(shí)現(xiàn)隔行隔列的賦值計(jì)算
      相關(guān)文章
      中文字幕亚洲日韩无线码| 亚洲精品亚洲人成在线麻豆| 亚洲成人激情小说| 亚洲Av无码精品色午夜| 久久精品国产亚洲综合色| 亚洲色成人WWW永久网站| 国产亚洲成人久久| 中文字幕在亚洲第一在线| 亚洲国产午夜福利在线播放| 亚洲精品乱码久久久久久V| 波多野结衣亚洲一级| 色噜噜亚洲男人的天堂| 亚洲成a人片在线看| 亚洲人成77777在线播放网站不卡| 亚洲人配人种jizz| 亚洲国产激情在线一区| 亚洲码欧美码一区二区三区| 亚洲国产欧美一区二区三区| 亚洲av无码成人精品区一本二本 | 亚洲精品tv久久久久久久久| 国产精品亚洲成在人线| 亚洲爆乳无码专区| 亚洲国产精品第一区二区| 久久精品国产精品亚洲毛片| 亚洲美女自拍视频| 亚洲啪啪免费视频| 亚洲性色AV日韩在线观看| 亚洲依依成人亚洲社区| 色天使色婷婷在线影院亚洲| 亚洲国产成人精品久久久国产成人一区二区三区综 | 噜噜噜亚洲色成人网站∨ | 亚洲欧洲日本在线| 亚洲精品亚洲人成在线观看| 久久青草亚洲AV无码麻豆| 亚洲视频小说图片| 亚洲国产日韩精品| 精品亚洲视频在线| 中文字幕亚洲一区| 婷婷亚洲综合五月天小说| 亚洲沟沟美女亚洲沟沟| 亚洲综合精品伊人久久|