一句話概括本文:
本節簡單介紹了什麼是Xposed,基本原理,如何建立一個Xposed專案以及Xposed常用的類與方法。
引言:
前面用Python利用itchat庫擼了篇:
接著小號貌似因為傳送資訊太頻繁和太快,被封了,限制了不能網頁端登入; 又開始折騰AccessibilityService無障礙服務,擼了兩篇:
慢慢地越發對這些小玩具感興趣,畢竟實用性強,好玩。在評論和群裡都有人提到 過Xposed,我自己之前也有點了解,Xposed並不是什麼新東西了,好幾年前 就有了,以前看到搞機(基)的人都覺得很牛逼哄哄,刷系統,root下,改下系統UI, 用各種各樣的外掛模組改什麼什麼,屌得不行。(真正屌的是做的那個人而不是用的那個...)
真正開始學的時候,其實Xposed並沒有想象中那麼複雜,原理和相關的API都很 簡單,難的是逆向,怎麼去實現你要Hook的功能:反編譯,除錯輸出,堆疊 跟蹤,抓包等等,在這個過程中你需要去分析很多很多東西,猜測除錯,有時候 折騰幾天可能毫無進展,不過也會收穫更多,比如你自己開發APP的時候也會 慢慢開始考慮安全相關的東西~
基礎就一節,原始碼分析一節,接著都是實戰,另外之前寫的Python學習之旅 也不會太監,老規矩,隨緣更新~
話不多說,開始本系列的教程吧~
1.Xposed是什麼
一個很牛逼的框架,可以在不修改APK的情況下影響程式的執行,比如: 直接把APP的介面改成自己想要的樣子,去掉介面裡不喜歡的東西, 自動搶紅包,訊息防撤回,步數修改等等;簡直酷得不行,網上有 很多外掛作者開發出來的優秀外掛,隨手開啟Xposed Installer下載 就有很多:
外掛用起來是挺爽的,不過呢,因為Xposed擁有最高許可權,如果不法分子 在外掛裡植入了惡意程式碼,比如登入劫持,偷偷採集你的賬號密碼傳送到 他們的手裡,如果涉及到了金錢,就很恐怖啦,所以在使用Xposed外掛的時候, 儘量選那些開源的,並進行程式碼review,看是否存在惡意程式碼,再進行安裝體驗 (開源不一定就沒問題,之前有個搶外賣紅包的開源專案在裡面加了一段挖礦程式碼, 令人窒息的操作!)
大概簡述下Xposed的原理吧,後面有一節會專門研究原始碼~
Android基於Linux,第一個啟動的程式自然是init程式,該程式會 啟動所有Android程式的父程式——Zygote(孵化)程式,該程式的啟動配置在 /init.rc指令碼中,而Zygote程式對應的執行檔案是**/system/bin/app_process**, 該檔案完成類庫的載入以及一些函式的呼叫工作。在Zygote程式建立後, 再fork出SystemServer程式和其他程式。
而Xposed Framework呢,就是用自己實現的app_process替換掉了系統原本 提供的app_process,載入一個額外的jar包,然後入口從原來的: **com.android.internal.osZygoteInit.main()**被替換成了: de.robv.android.xposed.XposedBridge.main(), 然後建立的Zygote程式就變成Hook的Zygote程式了,而後面Fork出來的程式 也是被Hook過的。這個Jar包在: /data/data/de.rbov.android.xposed.installer/bin/XposedBridge.jar
大概原理就是這樣,原始碼我還沒去擼,後面會研究一波,有說錯的再回來改。 另外使用Xposed模組是需要Root許可權的,怎麼Root,安裝這個框架, 網上的教程很多,不在本系列研究範圍以內!
相關文件:
- 官網:repo.xposed.info/
- 作者Github倉庫:github.com/rovo89
- 官方教程:github.com/rovo89/Xpos…
- XposedBridge.jar下載:jcenter.bintray.com/de/robv/and…
然後是Xposed Installer,由於Android 5.0以上採用ART,而5.0以下預設採用Dalvik, 所以是有兩個版本的Xposed,附上下載連結: Android 4.0.3-4.4:repo.xposed.info/module/de.r… Android 5.0以上::forum.xda-developers.com/showthread.…
PS:點下面這兩個地方即可下載:
2.建立一個Xposed工程
接著演示一波如何建立一個Xposed工程
- Step 1:新建一個工程,然後修改下AndroidManifest.xml,增加下面的程式碼:
- Step 2:build.gradle檔案新增庫依賴
可能會有的疑問:provided只提供編譯支援,不會寫到apk裡!!! 別手賤改成compile,裝上開啟後會報錯的!
- Step 3:res/asserts資料夾建立一個xposed_init檔案
XposedBridge會從assets 目錄中的xposed_init檔案中獲取入口點,比如我的:
- Step 4:編寫我們的入口點類
在此之前我們先修改下我們的MainActivity.java,修改下TextView顯示的文字:
程式碼很簡單,就是設定成"渣渣輝"而已,接著編寫我們的Xposed入口類:XposedInit.java
繼承了IXposedHookLoadPackage介面,重寫了handleLoadPackage方法, 判斷了下包名,如果是的,XposedHelpers.findAndHookMethod(), hook掉onCreate()方法,XC_MethodHook()重寫afterHookedMethod, 當onCreate()執行後會回撥這個方法,在這裡獲得TextView物件, 把文字修改成"貪玩難約",接著執行,安裝後需要重啟裝置。
重啟後,開啟應用,檢視是否生效:
生效了,log也能看到列印出來的日誌:
注意事項:
在執行Xposed之前,記得把InstallRun的鉤鉤去掉哦!
每次執行都需要重啟手機哈~ 知道怎麼建立一個Xposed專案後,接著就到API解釋了!
3.Xposed API相關介紹
PS:發現網上沒有什麼好的Xposed API的文件啊,這裡都是翻閱很多的出來的 網頁總結,如果英語好的,建議直接閱讀原始碼註釋!!!
1.例子裡用到的姿勢點
-
IXposedHookLoadPackage介面:App被載入的時候呼叫,用於App應用的Hook 回撥方法是:handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam)
-
XC_LoadPackage.LoadPackageParam:包含與正在載入的應用程式的有關資訊。
-
XposedHelpers.findAndHookMethod(要Hook的類,classLoader,方法名,引數,回撥物件) Hook一個方法的時候使用,回撥物件**XC_MethodHook()**需重寫兩個方法 beforeHookedMethod(MethodHookParam param):方法呼叫前執行 afterHookedMethod(MethodHookParam param) 方法呼叫後執行 注:可以呼叫param.setResult()設定方法的返回值!
-
MethodHookParam:包含與呼叫方法有關的資訊
比較關注的是這個thisObject,代表呼叫該方法的物件例項,如果是靜態方法 的話,返回一個Null,比如這裡呼叫onCreate()方法的是MainActivity,獲得 的自然是MainActivity例項。
接著是獲取成員變數,分為私有與非私有變數,非私有直接呼叫下述方法 即可獲得class
Class c = lpparam.classLoader.loadClass("com.coderpig.cpwechatxposed.MainActivity");
Field field = c.getField("tv");
複製程式碼
如果是私有,則需要先設定訪問許可權(setAccessible)
Class c = lpparam.classLoader.loadClass("com.coderpig.cpwechatxposed.MainActivity");
Field field = c.getDeclaredField("tv");
field.setAccessible(true);
複製程式碼
接著呼叫獲得該物件
TextView tv = (TextView) field.get(param.thisObject);
tv.setText("貪玩難約");
複製程式碼
3.補充姿勢點
-
IXposedHookZygoteInit:在Zygote啟動時呼叫,用於系統服務的Hook 回撥方法initZygote()
-
IXposedHookInitPackageResources:在資源佈局初始化時會回被執行(inflate方法) 回撥方法:handleInitPackageResources(XC_InitPackageResources.InitPackageResourcesParam resparam) InitPackageResourcesParam包含兩個引數,包名和XResource(資源相關)
有了這個XResource物件,就可以拿到佈局資源樹了,通過重寫hookLayout方法,
LayoutInflatedParam,裡面這個view就是佈局資源樹了,你可以拿到遍歷,拿到某個 特定控制元件,然後做一些騷操作。
XposeHelpers提供了一些輔助方法
-
callMethod(Object obj,String methodName, Object... args):在APP中呼叫特定方法; 引數依次是:呼叫方法的所在類,呼叫方法名,方法引數
-
findClass(String className,ClassLoader classLoader):獲取class類例項 引數依次是類名,類載入器
-
findMethodExact:通過反射查詢類的成員方法(可setAccessible(true)設定非私有)
-
findConstructorExact:通過反射查詢建構函式(同樣可設定可訪問下性)
-
findAndHookXXX:查詢並Hook
-
setXxx:通過反射設定物件資料成員的值
-
setStaticXxx:通過反射設定靜態變數的值
-
XposedBridge.log("日誌內容"):輸入日誌和寫入到/data/xposed/debug.log Xposed Installer日誌那裡可以看到!
-
內部類:通過$符號連結內部類
-
只能Hook方法與構造方法,不能Hook介面和抽象方法
4.小結
基礎的東西大概就這些,後續覺得有遺漏的回頭補,謝謝~
來啊,Py交易啊
想加群一起學習Py的可以加下,智障機器人小Pig
驗證通過後會自動傳送群聊連結加群連結,點選加入即可 (不要和機器人聊天=-=,就掛著拉人的,有問題到群裡講!)
歡迎各種像我一樣的Py初學者,Py大神加入,一起愉快地交流學♂習,van♂轉py。