xposed 原理分析


1.添加hook方法

首先是init進程打開 app_process,然后進入XposedInit.java main() - > initForZygote() 加入對ActivityThread.handleBindApplication() 的hook,找到Method對象

XposedBridge.hookMethod(method,callback) 加入到一個  key=method val=callbacks 的map中 sHookedMethodCallbacks

Native 方法 hookMethodNative(),當前在zygote中,zygote的app_process被xposed修改過,加載過這個方法。

然后是loadModules() 加載所有模塊app

 

App_process

先加載/system/framework/XposedBridge.jar 到 env CLASSPATH 中

然后啟動虛擬機,調用onVmCreatedCommon()加載native方法

加載jar路徑成功后到 de.robv.android.xposed.XposedBridge main() 中

ArtMethod* artMethod = ArtMethod::FromReflectedMethod(soa, javaReflectedMethod); //(soa = Method = jobject)

該方法根據 soa對象里的 artMethod int值經過一系列操作,asArtMethod()

得到artMethod,然后執行hook

artMethod->EnableXposedHook(soa, javaAdditionalInfo);  //EnableXposedHook 找不到定義

ArtMethod定義在android源碼中

class MANAGED ArtMethod FINAL : public Object

dvm的實現

Method* method = dvmSlotToMethod(declaredClass, slot);  //return &clazz->virtualMethods[slot];

保存原先的method副本到XposedHookInfo中。

method->nativeFunc = &hookedMethodCallback

method->insns = (const u2*) hookInfo;  //表示讓dvm判為內部native方法 = DalvikNativeFunc  =  typedef void (*DalvikNativeFunc)(const u4* args, JValue* pResult);

method->registersSize = method->insSize;

最主要的一個操作是 nativeFunc 指向自己的方法

完成HOOK

 

Method結構

struct Method {

ClassObject*    clazz;

u4              accessFlags;

u2             methodIndex;  //在虛方法表中的下標

508    u2              registersSize;  /* ins + locals 需要的寄存器數量  smali: .register */ 

509    u2              outsSize;

510    u2              insSize;

513    const char*     name; //方法名

523    DexProto        prototype;  //方法簽名  smali: (I[I)V     = void xxxxx(int,int[])

525    const char*     shorty;  /* short-form method descriptor string */

 

535    const u2*       insns;          /* 1.指令,在內存中映射的.dex   2.JNI 會把這里用作方法指針。 3.內部本地方法這里是null*/

536

537    /* JNI: cached argument and return-type hints */

538    int             jniArgInfo;

547    DalvikBridgeFunc nativeFunc;  //Jni方法指針,可以是具體方法或者JNIbridge 。DalvikBridgeFunc / DalvikNativeFunc insns == null 代表Jni方法(DalvikBridgeFunc ),否則等於內部方法(DalvikNativeFunc),

。。。

577    const RegisterMap* registerMap; //方法中用到的寄存器

。。。

581};

 

觸發

之后當這個方法被虛擬機調用時會調用 hookedMethodCallback()

然后會調用 java層的 handleHookedMethod()方法。

然后的主要流程是取出在hook時給的additionalInfo.callbacks 中的所有XC_MethodHook,調beforeHookedMethod(),invokeOriginalMethodNative()調原來的方法,然后是調用afterHookedMethod(),最后返回方法返回值。

invokeOriginalMethodNative() 通過 dvmInvokeMethod()調用原生方法

Art是 用 InvokeMethod() 調用原生方法

 

android_art/runtime

EableXposedHook   ArtMehtod 修改后的方法在這個修改后的 art 虛擬機工程里

xposedInstaller 安裝框架的時候,除了下載xposedBrage.jar 更換 app_Process 等,還從這個項目中下載 libart.so

 

 

1.掛載入口

xposedInitLib = dlsym(xposedLibHandle, "xposedInitLib") //根據 dvm 或 art 動態加載函數地址

xposedInitLib()

xposed->onVmCreated = &onVmCreatedCommon;

 

2.根據生命周期進入

虛擬機onVmCreated()

Xposed::onVmCreated() -》 onVmCreatedCommon()

onVmCreatedCommon()

initXposedBridge()

register_natives_XposedBridge()-》 注冊hookMethodNative native方法

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM