抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

coder-pig發表於2018-04-20

一句話概括本文

本節簡單介紹了什麼是Xposed,基本原理,如何建立一個Xposed專案以及Xposed常用的類與方法。


引言

前面用Python利用itchat庫擼了篇:

接著小號貌似因為傳送資訊太頻繁和太快,被封了,限制了不能網頁端登入; 又開始折騰AccessibilityService無障礙服務,擼了兩篇:

慢慢地越發對這些小玩具感興趣,畢竟實用性強,好玩。在評論和群裡都有人提到 過Xposed,我自己之前也有點了解,Xposed並不是什麼新東西了,好幾年前 就有了,以前看到搞機(基)的人都覺得很牛逼哄哄,刷系統,root下,改下系統UI, 用各種各樣的外掛模組改什麼什麼,屌得不行。(真正屌的是做的那個人而不是用的那個...)

真正開始學的時候,其實Xposed並沒有想象中那麼複雜,原理和相關的API都很 簡單,難的是逆向,怎麼去實現你要Hook的功能:反編譯,除錯輸出,堆疊 跟蹤,抓包等等,在這個過程中你需要去分析很多很多東西,猜測除錯,有時候 折騰幾天可能毫無進展,不過也會收穫更多,比如你自己開發APP的時候也會 慢慢開始考慮安全相關的東西~

基礎就一節,原始碼分析一節,接著都是實戰,另外之前寫的Python學習之旅 也不會太監,老規矩,隨緣更新~

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

話不多說,開始本系列的教程吧~


1.Xposed是什麼

一個很牛逼的框架,可以在不修改APK的情況下影響程式的執行,比如: 直接把APP的介面改成自己想要的樣子,去掉介面裡不喜歡的東西, 自動搶紅包,訊息防撤回,步數修改等等;簡直酷得不行,網上有 很多外掛作者開發出來的優秀外掛,隨手開啟Xposed Installer下載 就有很多:

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

外掛用起來是挺爽的,不過呢,因為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.4repo.xposed.info/module/de.r… Android 5.0以上:forum.xda-developers.com/showthread.…

PS:點下面這兩個地方即可下載:

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備


2.建立一個Xposed工程

接著演示一波如何建立一個Xposed工程

  • Step 1:新建一個工程,然後修改下AndroidManifest.xml,增加下面的程式碼:

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

  • Step 2build.gradle檔案新增庫依賴

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

可能會有的疑問:provided只提供編譯支援不會寫到apk裡!!! 別手賤改成compile,裝上開啟後會報錯的!

  • Step 3res/asserts資料夾建立一個xposed_init檔案

XposedBridge會從assets 目錄中的xposed_init檔案中獲取入口點,比如我的:

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

  • Step 4編寫我們的入口點類

在此之前我們先修改下我們的MainActivity.java,修改下TextView顯示的文字:

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

程式碼很簡單,就是設定成"渣渣輝"而已,接著編寫我們的Xposed入口類:XposedInit.java

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

繼承了IXposedHookLoadPackage介面,重寫了handleLoadPackage方法, 判斷了下包名,如果是的,XposedHelpers.findAndHookMethod(), hook掉onCreate()方法,XC_MethodHook()重寫afterHookedMethod, 當onCreate()執行後會回撥這個方法,在這裡獲得TextView物件, 把文字修改成"貪玩難約",接著執行,安裝後需要重啟裝置。

重啟後,開啟應用,檢視是否生效:

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

生效了,log也能看到列印出來的日誌:

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

注意事項

在執行Xposed之前,記得把InstallRun的鉤鉤去掉哦!

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

每次執行都需要重啟手機哈~ 知道怎麼建立一個Xposed專案後,接著就到API解釋了!


3.Xposed API相關介紹

PS:發現網上沒有什麼好的Xposed API的文件啊,這裡都是翻閱很多的出來的 網頁總結,如果英語好的,建議直接閱讀原始碼註釋!!!


1.例子裡用到的姿勢點

  • IXposedHookLoadPackage介面:App被載入的時候呼叫,用於App應用的Hook 回撥方法是:handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam)

  • XC_LoadPackage.LoadPackageParam:包含與正在載入的應用程式的有關資訊。

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

  • XposedHelpers.findAndHookMethod(要Hook的類,classLoader,方法名,引數,回撥物件) Hook一個方法的時候使用,回撥物件**XC_MethodHook()**需重寫兩個方法 beforeHookedMethod(MethodHookParam param):方法呼叫前執行 afterHookedMethod(MethodHookParam param) 方法呼叫後執行 注:可以呼叫param.setResult()設定方法的返回值!

  • MethodHookParam:包含與呼叫方法有關的資訊

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

比較關注的是這個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(資源相關)

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

有了這個XResource物件,就可以拿到佈局資源樹了,通過重寫hookLayout方法,

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

LayoutInflatedParam,裡面這個view就是佈局資源樹了,你可以拿到遍歷,拿到某個 特定控制元件,然後做一些騷操作。

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

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

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備

驗證通過後會自動傳送群聊連結加群連結,點選加入即可 (不要和機器人聊天=-=,就掛著拉人的,有問題到群裡講!)

歡迎各種像我一樣的Py初學者,Py大神加入,一起愉快地交流學♂習,van♂轉py。

抱歉,Xposed真的可以為所欲為——1.基礎知識儲備


相關文章