一句話歸納本文:php
本節簡單介紹了什麼是Xposed,基本原理,如何建立一個Xposed項目以及Xposed經常使用的類與方法。java
引言:android
前面用Python利用itchat庫擼了篇:git
接着小號貌似由於發送信息太頻繁和太快,被封了,限制了不能網頁端登陸; 又開始折騰AccessibilityService無障礙服務,擼了兩篇:github
慢慢地愈加對這些小玩具感興趣,畢竟實用性強,好玩。在評論和羣裏都有人提到 過Xposed,我本身以前也有點了解,Xposed並非什麼新東西了,好幾年前 就有了,之前看到搞機(基)的人都以爲很牛逼哄哄,刷系統,root下,改下系統UI, 用各類各樣的插件模塊改什麼什麼,屌得不行。(真正屌的是作的那我的而不是用的那個...)api
真正開始學的時候,其實Xposed並無想象中那麼複雜,原理和相關的API都很 簡單,難的是逆向,怎麼去實現你要Hook的功能:反編譯,調試輸出,堆棧 跟蹤,抓包等等,在這個過程當中你須要去分析不少不少東西,猜想調試,有時候 折騰幾天可能毫無進展,不過也會收穫更多,好比你本身開發APP的時候也會 慢慢開始考慮安全相關的東西~安全
基礎就一節,源碼分析一節,接着都是實戰,另外以前寫的Python學習之旅 也不會太監,老規矩,隨緣更新~bash
話很少說,開始本系列的教程吧~微信
一個很牛逼的框架,能夠在不修改APK的狀況下影響程序的運行,好比: 直接把APP的界面改爲本身想要的樣子,去掉界面裏不喜歡的東西, 自動搶紅包,消息防撤回,步數修改等等;簡直酷得不行,網上有 不少插件做者開發出來的優秀插件,隨手打開Xposed Installer下載 就有不少:app
插件用起來是挺爽的,不過呢,由於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,安裝這個框架, 網上的教程不少,不在本系列研究範圍之內!
相關文檔:
而後是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:點下面這兩個地方便可下載:
接着演示一波如何建立一個Xposed工程
可能會有的疑問:provided只提供編譯支持,不會寫到apk裏!!! 別手賤改爲compile,裝上打開後會報錯的!
XposedBridge會從assets 目錄中的xposed_init文件中獲取入口點,好比個人:
在此以前咱們先修改下咱們的MainActivity.java,修改下TextView顯示的文字:
代碼很簡單,就是設置成"渣渣輝"而已,接着編寫咱們的Xposed入口類:XposedInit.java
繼承了IXposedHookLoadPackage接口,重寫了handleLoadPackage方法, 判斷了下包名,若是是的,XposedHelpers.findAndHookMethod(), hook掉onCreate()方法,XC_MethodHook()重寫afterHookedMethod, 當onCreate()執行後會回調這個方法,在這裏得到TextView對象, 把文字修改爲"貪玩難約",接着運行,安裝後須要重啓設備。
重啓後,打開應用,查看是否生效:
生效了,log也能看到打印出來的日誌:
注意事項:
在運行Xposed以前,記得把InstallRun的鉤鉤去掉哦!
每次運行都須要重啓手機哈~ 知道怎麼建立一個Xposed項目後,接着就到API解釋了!
PS:發現網上沒有什麼好的Xposed API的文檔啊,這裏都是翻閱不少的出來的 網頁總結,若是英語好的,建議直接閱讀源碼註釋!!!
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("貪玩難約");
複製代碼
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接口和抽象方法
基礎的東西大概就這些,後續以爲有遺漏的回頭補,謝謝~
來啊,Py交易啊
想加羣一塊兒學習Py的能夠加下,智障機器人小Pig
驗證經過後會自動發送羣聊連接加羣連接,點擊加入便可 (不要和機器人聊天=-=,就掛着拉人的,有問題到羣裏講!)
歡迎各類像我同樣的Py初學者,Py大神加入,一塊兒愉快地交流學♂習,van♂轉py。